# HG changeset patch # User jfranck # Date 1346405866 -3600 # Node ID 4d519199a6aa738da74db6e3280473b1798504f1 # Parent bee2d435e11f0d4bd42f7dd99146ac6c4e354dbb 7151010: Add compiler support for repeating annotations Reviewed-by: jjg, mcimadamore diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.code; + +import java.util.Map; +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.comp.Annotate; +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Pair; + +import static com.sun.tools.javac.code.Kinds.PCK; +import com.sun.tools.javac.util.*; + +/** + * Container for all annotations (attributes in javac) on a Symbol. + * + * This class is explicitly mutable. Its contents will change when attributes + * are annotated onto the Symbol. However this class depends on the facts that + * List (in javac) is immutable. + * + * An instance of this class can be in one of three states: + * + * NOT_STARTED indicates that the Symbol this instance belongs to have not been + * annotated (yet). Specifically if the declaration is not annotated this + * instance will never move past NOT_STARTED. You can never go back to + * NOT_STARTED. + * + * IN_PROGRESS annotations have been found on the declaration. Will be processed + * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list + * of attributes (and this moves out of the IN_PROGRESS state). + * + * "unnamed" this Annotations contains some attributes, possibly the final set. + * While in this state you can only prepend or append to the attributes not set + * it directly. You can also move back to the IN_PROGRESS sate using reset(). + * + *

This is NOT part of any supported API. If you write code that depends + * on this, you do so at your own risk. This code and its internal interfaces + * are subject to change or deletion without notice. + */ +public class Annotations { + + private static final List NOT_STARTED = List.of(null); + private static final List IN_PROGRESS = List.of(null); + /* + * This field should never be null + */ + private List attributes = NOT_STARTED; + /* + * The Symbol this Annotatios belong to + */ + private final Symbol s; + + public Annotations(Symbol s) { + this.s = s; + } + + public List getAttributes() { + return filterSentinels(attributes); + } + + public void setAttributes(List a) { + Assert.check(pendingCompletion() || !isStarted()); + if (a == null) { + throw new NullPointerException(); + } + attributes = a; + } + + public void setAttributes(Annotations other) { + if (other == null) { + throw new NullPointerException(); + } + setAttributes(other.getAttributes()); + } + + public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) { + Assert.check(pendingCompletion() || (!isStarted() && s.kind == PCK)); + + Map> annotated = ctx.annotated; + boolean atLeastOneRepeated = false; + List buf = List.nil(); + for (ListBuffer lb : annotated.values()) { + if (lb.size() == 1) { + buf = buf.prepend(lb.first()); + } else { // repeated + buf = buf.prepend(new Placeholder(lb.toList(), s)); + atLeastOneRepeated = true; + } + } + + // Add non-repeating attributes + setAttributes(buf.reverse()); + + if (atLeastOneRepeated) { + // The Symbol s is now annotated with a combination of + // finished non-repeating annotations and placeholders for + // repeating annotations. + // + // We need to do this in two passes because when creating + // a container for a repeating annotation we must + // guarantee that the @ContainedBy on the + // contained annotation is fully annotated + // + // The way we force this order is to do all repeating + // annotations in a pass after all non-repeating are + // finished. This will work because @ContainedBy + // is non-repeating and therefore will be annotated in the + // fist pass. + + // Queue a pass that will replace Attribute.Placeholders + // with Attribute.Compound (made from synthesized containers). + ctx.annotateRepeated(new Annotate.Annotator() { + + @Override + public String toString() { + return "repeated annotation pass of: " + s + " in: " + s.owner; + } + + @Override + public void enterAnnotation() { + complete(ctx); + } + }); + } + } + + public Annotations reset() { + attributes = IN_PROGRESS; + return this; + } + + public boolean isEmpty() { + return !isStarted() + || pendingCompletion() + || attributes.isEmpty(); + } + + public boolean pendingCompletion() { + return attributes == IN_PROGRESS; + } + + public Annotations append(List l) { + attributes = filterSentinels(attributes); + + if (l.isEmpty()) { + ; // no-op + } else if (attributes.isEmpty()) { + attributes = l; + } else { + attributes = attributes.appendList(l); + } + return this; + } + + public Annotations prepend(List l) { + attributes = filterSentinels(attributes); + + if (l.isEmpty()) { + ; // no-op + } else if (attributes.isEmpty()) { + attributes = l; + } else { + attributes = attributes.prependList(l); + } + return this; + } + + private List filterSentinels(List a) { + return (a == IN_PROGRESS || a == NOT_STARTED) + ? List.nil() + : a; + } + + private boolean isStarted() { + return attributes != NOT_STARTED; + } + + private List getPlaceholders() { + List res = List.nil(); + for (Attribute.Compound a : filterSentinels(attributes)) { + if (a instanceof Placeholder) { + res = res.prepend(a); + } + } + return res.reverse(); + } + + /* + * Replace Placeholders for repeating annotations with their containers + */ + private void complete(Annotate.AnnotateRepeatedContext ctx) { + Assert.check(!pendingCompletion()); + Log log = ctx.log; + Env env = ctx.env; + JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); + try { + + if (isEmpty()) { + return; + } + + List result = List.nil(); + for (Attribute.Compound a : getAttributes()) { + if (a instanceof Placeholder) { + Attribute.Compound replacement = replaceOne((Placeholder) a, ctx); + + if (null != replacement) { + result = result.prepend(replacement); + } + } else { + result = result.prepend(a); + } + } + + attributes = result.reverse(); + + Assert.check(Annotations.this.getPlaceholders().isEmpty()); + } finally { + log.useSource(oldSource); + } + } + + private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) { + Log log = ctx.log; + + // Process repeated annotations + Attribute.Compound validRepeated = + ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor()); + + if (validRepeated != null) { + // Check that the container isn't manually + // present along with repeated instances of + // its contained annotation. + ListBuffer manualContainer = ctx.annotated.get(validRepeated.type.tsym); + if (manualContainer != null) { + log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present", + manualContainer.first().type.tsym); + } + } + + // A null return will delete the Placeholder + return validRepeated; + + } + + private static class Placeholder extends Attribute.Compound { + + private List placeholderFor; + private Symbol on; + + public Placeholder(List placeholderFor, Symbol on) { + super(Type.noType, List.>nil()); + this.placeholderFor = placeholderFor; + this.on = on; + } + + @Override + public String toString() { + return ""; + } + + public List getPlaceholderFor() { + return placeholderFor; + } + } +} diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,11 +103,11 @@ * represented as a ClassSymbol. */ public static class Class extends Attribute { - public final Type type; + public final Type classType; public void accept(Visitor v) { v.visitClass(this); } public Class(Types types, Type type) { super(makeClassType(types, type)); - this.type = type; + this.classType = type; } static Type makeClassType(Types types, Type type) { Type arg = type.isPrimitive() @@ -118,13 +118,13 @@ types.syms.classType.tsym); } public String toString() { - return type + ".class"; + return classType + ".class"; } public Type getValue() { - return type; + return classType; } public R accept(AnnotationValueVisitor v, P p) { - return v.visitType(type, p); + return v.visitType(classType, p); } } @@ -212,6 +212,12 @@ super(type); this.values = values; } + + public Array(Type type, List values) { + super(type); + this.values = values.toArray(new Attribute[values.size()]); + } + public void accept(Visitor v) { v.visitArray(this); } public String toString() { StringBuilder buf = new StringBuilder(); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Lint.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,16 +70,16 @@ * Returns the result of combining the values in this object with * the given annotations. */ - public Lint augment(List attrs) { - return augmentor.augment(this, attrs); + public Lint augment(Annotations annots) { + return augmentor.augment(this, annots.getAttributes()); } /** * Returns the result of combining the values in this object with * the given annotations and flags. */ - public Lint augment(List attrs, long flags) { - Lint l = augmentor.augment(this, attrs); + public Lint augment(Annotations annots, long flags) { + Lint l = augmentor.augment(this, annots.getAttributes()); if ((flags & DEPRECATED) != 0) { if (l == this) l = new Lint(this); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Source.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Aug 31 10:37:46 2012 +0100 @@ -203,6 +203,9 @@ public boolean allowEffectivelyFinalInInnerClasses() { return compareTo(JDK1_8) >= 0; } + public boolean allowRepeatedAnnotations() { + return compareTo(JDK1_8) >= 0; + } public static SourceVersion toSourceVersion(Source source) { switch(source) { case JDK1_2: diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Aug 31 10:37:46 2012 +0100 @@ -72,22 +72,24 @@ */ public long flags() { return flags_field; } - /** The attributes of this symbol. + /** The attributes of this symbol are contained in this + * Annotations. The Annotations instance is NOT immutable. */ - public List attributes_field; + public final Annotations annotations = new Annotations(this); /** An accessor method for the attributes of this symbol. * Attributes of class symbols should be accessed through the accessor * method to make sure that the class symbol is loaded. */ public List getAnnotationMirrors() { - return Assert.checkNonNull(attributes_field); + return Assert.checkNonNull(annotations.getAttributes()); } /** Fetch a particular annotation from a symbol. */ public Attribute.Compound attribute(Symbol anno) { - for (Attribute.Compound a : getAnnotationMirrors()) + for (Attribute.Compound a : getAnnotationMirrors()) { if (a.type.tsym == anno) return a; + } return null; } @@ -120,7 +122,6 @@ this.owner = owner; this.completer = null; this.erasure_field = null; - this.attributes_field = List.nil(); this.name = name; } @@ -657,10 +658,11 @@ if (completer != null) complete(); if (package_info != null && package_info.completer != null) { package_info.complete(); - if (attributes_field.isEmpty()) - attributes_field = package_info.attributes_field; + if (annotations.isEmpty()) { + annotations.setAttributes(package_info.annotations); } - return Assert.checkNonNull(attributes_field); + } + return Assert.checkNonNull(annotations.getAttributes()); } /** A package "exists" if a type or package that exists has @@ -762,7 +764,7 @@ public List getAnnotationMirrors() { if (completer != null) complete(); - return Assert.checkNonNull(attributes_field); + return Assert.checkNonNull(annotations.getAttributes()); } public Type erasure(Types types) { diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Aug 31 10:37:46 2012 +0100 @@ -156,6 +156,10 @@ public final Type systemType; public final Type autoCloseableType; public final Type trustMeType; + public final Type containedByType; + public final Type containerForType; + public final Type documentedType; + public final Type elementTypeType; /** The symbol representing the length field of an array. */ @@ -468,6 +472,10 @@ deprecatedType = enterClass("java.lang.Deprecated"); suppressWarningsType = enterClass("java.lang.SuppressWarnings"); inheritedType = enterClass("java.lang.annotation.Inherited"); + containedByType = enterClass("java.lang.annotation.ContainedBy"); + containerForType = enterClass("java.lang.annotation.ContainerFor"); + documentedType = enterClass("java.lang.annotation.Documented"); + elementTypeType = enterClass("java.lang.annotation.ElementType"); systemType = enterClass("java.lang.System"); autoCloseableType = enterClass("java.lang.AutoCloseable"); autoCloseableClose = new MethodSymbol(PUBLIC, diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Aug 31 10:37:46 2012 +0100 @@ -1358,6 +1358,20 @@ } return result; } + + /** + * Returns an ArrayType with the component type t + * + * @param t The component type of the ArrayType + * @return the ArrayType for the given component + */ + public ArrayType makeArrayType(Type t) { + if (t.tag == VOID || + t.tag >= PACKAGE) { + Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString()); + } + return new ArrayType(t, syms.arrayClass); + } // // @@ -3811,8 +3825,12 @@ // public RetentionPolicy getRetention(Attribute.Compound a) { + return getRetention(a.type.tsym); + } + + public RetentionPolicy getRetention(Symbol sym) { RetentionPolicy vis = RetentionPolicy.CLASS; // the default - Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym); + Attribute.Compound c = sym.attribute(syms.retentionType.tsym); if (c != null) { Attribute value = c.member(names.value); if (value != null && value instanceof Attribute.Enum) { diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,11 @@ package com.sun.tools.javac.comp; +import java.util.Map; +import java.util.Objects; + import com.sun.tools.javac.util.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; @@ -83,8 +87,9 @@ private int enterCount = 0; ListBuffer q = new ListBuffer(); + ListBuffer repeatedQ = new ListBuffer(); - public void later(Annotator a) { + public void normal(Annotator a) { q.append(a); } @@ -92,6 +97,10 @@ q.prepend(a); } + public void repeated(Annotator a) { + repeatedQ.append(a); + } + /** Called when the Enter phase starts. */ public void enterStart() { enterCount++; @@ -109,6 +118,10 @@ try { while (q.nonEmpty()) q.next().enterAnnotation(); + + while (repeatedQ.nonEmpty()) { + repeatedQ.next().enterAnnotation(); + } } finally { enterCount--; } @@ -124,6 +137,53 @@ String toString(); } + /** + * This context contains all the information needed to synthesize new + * annotations trees by the completer for repeating annotations. + */ + public class AnnotateRepeatedContext { + public final Env env; + public final Map> annotated; + public final Map pos; + public final Log log; + + public AnnotateRepeatedContext(Env env, + Map> annotated, + Map pos, + Log log) { + Objects.requireNonNull(env); + Objects.requireNonNull(annotated); + Objects.requireNonNull(pos); + Objects.requireNonNull(log); + + this.env = env; + this.annotated = annotated; + this.pos = pos; + this.log = log; + } + + /** + * Process a list of repeating annotations returning a new + * Attribute.Compound that is the attribute for the synthesized tree + * for the container. + * + * @param repeatingAnnotations a List of repeating annotations + * @return a new Attribute.Compound that is the container for the repeatingAnnotations + */ + public Attribute.Compound processRepeatedAnnotations(List repeatingAnnotations) { + return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this); + } + + /** + * Queue the Annotator a on the repeating annotations queue of the + * Annotate instance this context belongs to. + * + * @param a the Annotator to enqueue for repeating annotation annotating + */ + public void annotateRepeated(Annotator a) { + Annotate.this.repeated(a); + } + } /* ******************************************************************** * Compute an attribute from its annotation. @@ -268,4 +328,219 @@ log.error(tree.pos(), "annotation.value.not.allowable.type"); return new Attribute.Error(attr.attribExpr(tree, env, expected)); } + + /* ********************************* + * Support for repeating annotations + ***********************************/ + + /* Process repeated annotations. This method returns the + * synthesized container annotation or null IFF all repeating + * annotation are invalid. This method reports errors/warnings. + */ + private Attribute.Compound processRepeatedAnnotations(List annotations, + AnnotateRepeatedContext ctx) { + Attribute.Compound firstOccurrence = annotations.head; + List repeated = List.nil(); + Type origAnnoType; + Type arrayOfOrigAnnoType = null; + Type targetContainerType = null; + MethodSymbol containerValueSymbol = null; + + Assert.check(!annotations.isEmpty() && + !annotations.tail.isEmpty()); // i.e. size() > 1 + + for (List al = annotations; + !al.isEmpty(); + al = al.tail) + { + Attribute.Compound currentAnno = al.head; + + origAnnoType = currentAnno.type; + if (arrayOfOrigAnnoType == null) { + arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); } + + Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno)); + if (currentContainerType == null) { + continue; + } + // Assert that the target Container is == for all repeated + // annos of the same annotation type, the types should + // come from the same Symbol, i.e. be '==' + Assert.check(targetContainerType == null || currentContainerType == targetContainerType); + targetContainerType = currentContainerType; + + containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno)); + + if (containerValueSymbol == null) { // Check of CA type failed + // errors are already reported + continue; + } + + repeated = repeated.prepend(currentAnno); + } + + if (!repeated.isEmpty()) { + repeated = repeated.reverse(); + JCAnnotation annoTree; + TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); + Pair p = + new Pair(containerValueSymbol, + new Attribute.Array(arrayOfOrigAnnoType, repeated)); + annoTree = m.Annotation(new Attribute.Compound(targetContainerType, + List.of(p))); + Attribute.Compound c = enterAnnotation(annoTree, + targetContainerType, + ctx.env); + return c; + } else { + return null; // errors should have been reported elsewhere + } + } + + /** Fetches the actual Type that should be the containing annotation. */ + private Type getContainingType(Attribute.Compound currentAnno, + DiagnosticPosition pos) + { + Type origAnnoType = currentAnno.type; + TypeSymbol origAnnoDecl = origAnnoType.tsym; + + // Fetch the ContainedBy annotation from the current + // annotation's declaration, or null if it has none + Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym); + if (ca == null) { // has no ContainedBy annotation + log.error(pos, "duplicate.annotation.missing.container", origAnnoType); + return null; + } + + return filterSame(extractContainingType(ca, pos, origAnnoDecl), + origAnnoType); + } + + // returns null if t is same as 's', returns 't' otherwise + private Type filterSame(Type t, Type s) { + if (t == null || s == null) { + return t; + } + + return types.isSameType(t, s) ? null : t; + } + + /** Extract the actual Type to be used for a containing annotation. */ + private Type extractContainingType(Attribute.Compound ca, + DiagnosticPosition pos, + TypeSymbol annoDecl) + { + // The next three checks check that the ContainedBy annotation + // on the declaration of the annotation type that is repeating is + // valid. + + // ContainedBy must have at least one element + if (ca.values.isEmpty()) { + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + Pair p = ca.values.head; + Name name = p.fst.name; + if (name != names.value) { // should contain only one element, named "value" + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class + log.error(pos, "invalid.containedby.annotation", annoDecl); + return null; + } + + return ((Attribute.Class)p.snd).getValue(); + } + + /* Validate that the suggested targetContainerType Type is a valid + * container type for repeated instances of originalAnnoType + * annotations. Return null and report errors if this is not the + * case, return the MethodSymbol of the value element in + * targetContainerType if it is suitable (this is needed to + * synthesize the container). */ + private MethodSymbol validateContainer(Type targetContainerType, + Type originalAnnoType, + DiagnosticPosition pos) { + MethodSymbol containerValueSymbol = null; + boolean fatalError = false; + + // Validate that there is a (and only 1) value method + Scope scope = targetContainerType.tsym.members(); + int nr_value_elems = 0; + boolean error = false; + for(Symbol elm : scope.getElementsByName(names.value)) { + nr_value_elems++; + + if (nr_value_elems == 1 && + elm.kind == Kinds.MTH) { + containerValueSymbol = (MethodSymbol)elm; + } else { + error = true; + } + } + if (error) { + log.error(pos, + "invalid.containedby.annotation.multiple.values", + targetContainerType, + nr_value_elems); + return null; + } else if (nr_value_elems == 0) { + log.error(pos, + "invalid.containedby.annotation.no.value", + targetContainerType); + return null; + } + + // validate that the 'value' element is a method + // probably "impossible" to fail this + if (containerValueSymbol.kind != Kinds.MTH) { + log.error(pos, + "invalid.containedby.annotation.invalid.value", + targetContainerType); + fatalError = true; + } + + // validate that the 'value' element has the correct return type + // i.e. array of original anno + Type valueRetType = containerValueSymbol.type.getReturnType(); + Type expectedType = types.makeArrayType(originalAnnoType); + if (!(types.isArray(valueRetType) && + types.isSameType(expectedType, valueRetType))) { + log.error(pos, + "invalid.containedby.annotation.value.return", + targetContainerType, + valueRetType, + expectedType); + fatalError = true; + } + + // validate that all other elements of containing type has defaults + scope = targetContainerType.tsym.members(); + error = false; + for(Symbol elm : scope.getElements()) { + if (elm.name != names.value && + elm.kind == Kinds.MTH && + ((MethodSymbol)elm).defaultValue == null) { + log.error(pos, + "invalid.containedby.annotation.elem.nondefault", + targetContainerType, + elm); + containerValueSymbol = null; + error = true; + } + } + if (error) { + fatalError = true; + } + + // Explicitly no check for/validity of @ContainerFor. That is + // done on declaration of the container, and at reflect time. + + // The rest of the conditions for a valid containing annotation are made + // in Check.validateRepeatedAnnotaton(); + + return fatalError ? null : containerValueSymbol; + } +} diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Aug 31 10:37:46 2012 +0100 @@ -662,10 +662,12 @@ // env.info.enclVar.attributes_field might not yet have been evaluated, and so might be // null. In that case, calling augment will throw an NPE. To avoid this, for now we // revert to the jdk 6 behavior and ignore the (unevaluated) attributes. - if (env.info.enclVar.attributes_field == null) + if (env.info.enclVar.annotations.pendingCompletion()) { env.info.lint = lintEnv.info.lint; - else - env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags()); + } else { + env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations, + env.info.enclVar.flags()); + } Lint prevLint = chk.setLint(env.info.lint); JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); @@ -776,7 +778,7 @@ public void visitMethodDef(JCMethodDecl tree) { MethodSymbol m = tree.sym; - Lint lint = env.info.lint.augment(m.attributes_field, m.flags()); + Lint lint = env.info.lint.augment(m.annotations, m.flags()); Lint prevLint = chk.setLint(lint); MethodSymbol prevMethod = chk.setMethod(m); try { @@ -921,7 +923,7 @@ } VarSymbol v = tree.sym; - Lint lint = env.info.lint.augment(v.attributes_field, v.flags()); + Lint lint = env.info.lint.augment(v.annotations, v.flags()); Lint prevLint = chk.setLint(lint); // Check that the variable's declared type is well-formed. @@ -3069,7 +3071,7 @@ lintEnv = lintEnv.next; // Having found the enclosing lint value, we can initialize the lint value for this class - env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags()); + env.info.lint = lintEnv.info.lint.augment(c.annotations, c.flags()); Lint prevLint = chk.setLint(env.info.lint); JavaFileObject prev = log.useSource(c.sourcefile); @@ -3133,6 +3135,26 @@ if (tree.typarams.nonEmpty()) log.error(tree.typarams.head.pos(), "intf.annotation.cant.have.type.params"); + + // If this annotation has a @ContainedBy, validate + Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym); + if (containedBy != null) { + // get diagnositc position for error reporting + DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type); + Assert.checkNonNull(cbPos); + + chk.validateContainedBy(c, containedBy, cbPos); + } + + // If this annotation has a @ContainerFor, validate + Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym); + if (containerFor != null) { + // get diagnositc position for error reporting + DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type); + Assert.checkNonNull(cfPos); + + chk.validateContainerFor(c, containerFor, cfPos); + } } else { // Check that all extended classes and interfaces // are compatible (i.e. no two define methods with same arguments @@ -3194,6 +3216,16 @@ } } // where + /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ + private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) { + for(List al = tree.mods.annotations; !al.isEmpty(); al = al.tail) { + if (types.isSameType(al.head.annotationType.type, t)) + return al.head.pos(); + } + + return null; + } + /** check if a class is a subtype of Serializable, if that is available. */ private boolean isSerializable(ClassSymbol c) { try { diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Aug 31 10:37:46 2012 +0100 @@ -69,7 +69,6 @@ private final Infer infer; private final Types types; private final JCDiagnostic.Factory diags; - private final boolean skipAnnotations; private boolean warnOnSyntheticConflicts; private boolean suppressAbortOnBadClassFile; private boolean enableSunApiLintControl; @@ -113,7 +112,6 @@ allowCovariantReturns = source.allowCovariantReturns(); allowSimplifiedVarargs = source.allowSimplifiedVarargs(); complexInference = options.isSet("complexinference"); - skipAnnotations = options.isSet("skipAnnotations"); warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); enableSunApiLintControl = options.isSet("enableSunApiLintControl"); @@ -2422,14 +2420,13 @@ /** Check the annotations of a symbol. */ public void validateAnnotations(List annotations, Symbol s) { - if (skipAnnotations) return; for (JCAnnotation a : annotations) validateAnnotation(a, s); } /** Check an annotation of a symbol. */ - public void validateAnnotation(JCAnnotation a, Symbol s) { + private void validateAnnotation(JCAnnotation a, Symbol s) { validateAnnotationTree(a); if (!annotationApplicable(a, s)) @@ -2441,6 +2438,215 @@ } } + /** + * Validate the proposed container 'containedBy' on the + * annotation type symbol 's'. Report errors at position + * 'pos'. + * + * @param s The (annotation)type declaration annotated with a @ContainedBy + * @param containerAnno the @ContainedBy on 's' + * @param pos where to report errors + */ + public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { + Assert.check(types.isSameType(containedBy.type, syms.containedByType)); + + Type t = null; + List> l = containedBy.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containedby", s, containedBy); + return; + } + + validateHasContainerFor(t.tsym, s, pos); + validateRetention(t.tsym, s, pos); + validateDocumented(t.tsym, s, pos); + validateInherited(t.tsym, s, pos); + validateTarget(t.tsym, s, pos); + } + + /** + * Validate the proposed container 'containerFor' on the + * annotation type symbol 's'. Report errors at position + * 'pos'. + * + * @param s The (annotation)type declaration annotated with a @ContainerFor + * @param containerFor the @ContainedFor on 's' + * @param pos where to report errors + */ + public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { + Assert.check(types.isSameType(containerFor.type, syms.containerForType)); + + Type t = null; + List> l = containerFor.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containerfor", s, containerFor); + return; + } + + validateHasContainedBy(t.tsym, s, pos); + } + + private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { + Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym); + + if (containedBy == null) { + log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym); + return; + } + + Type t = null; + List> l = containedBy.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containedby", container, contained); + return; + } + + if (!types.isSameType(t, contained.type)) + log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained); + } + + private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { + Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym); + + if (containerFor == null) { + log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym); + return; + } + + Type t = null; + List> l = containerFor.values; + if (!l.isEmpty()) { + Assert.check(l.head.fst.name == names.value); + t = ((Attribute.Class)l.head.snd).getValue(); + } + + if (t == null) { + log.error(pos, "invalid.container.wrong.containerfor", container, contained); + return; + } + + if (!types.isSameType(t, contained.type)) + log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained); + } + + private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { + Attribute.RetentionPolicy containerRetention = types.getRetention(container); + Attribute.RetentionPolicy containedRetention = types.getRetention(contained); + + boolean error = false; + switch (containedRetention) { + case RUNTIME: + if (containerRetention != Attribute.RetentionPolicy.RUNTIME) { + error = true; + } + break; + case CLASS: + if (containerRetention == Attribute.RetentionPolicy.SOURCE) { + error = true; + } + } + if (error ) { + log.error(pos, "invalid.containedby.annotation.retention", + container, containerRetention, + contained, containedRetention); + } + } + + private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { + if (contained.attribute(syms.documentedType.tsym) != null) { + if (container.attribute(syms.documentedType.tsym) == null) { + log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); + } + } + } + + private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { + if (contained.attribute(syms.inheritedType.tsym) != null) { + if (container.attribute(syms.inheritedType.tsym) == null) { + log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); + } + } + } + + private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { + Attribute.Array containedTarget = getAttributeTargetAttribute(contained); + + // If contained has no Target, we are done + if (containedTarget == null) { + return; + } + + // If contained has Target m1, container must have a Target + // annotation, m2, and m2 must be a subset of m1. (This is + // trivially true if contained has no target as per above). + + // contained has target, but container has not, error + Attribute.Array containerTarget = getAttributeTargetAttribute(container); + if (containerTarget == null) { + log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + return; + } + + Set containerTargets = new HashSet(); + for (Attribute app : containerTarget.values) { + if (!(app instanceof Attribute.Enum)) { + continue; // recovery + } + Attribute.Enum e = (Attribute.Enum)app; + containerTargets.add(e.value.name); + } + + Set containedTargets = new HashSet(); + for (Attribute app : containedTarget.values) { + if (!(app instanceof Attribute.Enum)) { + continue; // recovery + } + Attribute.Enum e = (Attribute.Enum)app; + containedTargets.add(e.value.name); + } + + if (!isTargetSubset(containedTargets, containerTargets)) { + log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + } + } + + /** Checks that t is a subset of s, with respect to ElementType + * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE} + */ + private boolean isTargetSubset(Set s, Set t) { + // Check that all elements in t are present in s + for (Name n2 : t) { + boolean currentElementOk = false; + for (Name n1 : s) { + if (n1 == n2) { + currentElementOk = true; + break; + } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) { + currentElementOk = true; + break; + } + } + if (!currentElementOk) + return false; + } + return true; + } + /** Is s a method symbol that overrides a method in a superclass? */ boolean isOverrider(Symbol s) { if (s.kind != MTH || s.isStatic()) @@ -2461,12 +2667,10 @@ /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { - Attribute.Compound atTarget = - a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); - if (atTarget == null) return true; - Attribute atValue = atTarget.member(names.value); - if (!(atValue instanceof Attribute.Array)) return true; // error recovery - Attribute.Array arr = (Attribute.Array) atValue; + Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); + if (arr == null) { + return true; + } for (Attribute app : arr.values) { if (!(app instanceof Attribute.Enum)) return true; // recovery Attribute.Enum e = (Attribute.Enum) app; @@ -2508,6 +2712,16 @@ return false; } + + Attribute.Array getAttributeTargetAttribute(Symbol s) { + Attribute.Compound atTarget = + s.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) return null; // ok, is applicable + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) return null; // error recovery + return (Attribute.Array) atValue; + } + /** Check an annotation value. */ public void validateAnnotation(JCAnnotation a) { diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Aug 31 10:37:46 2012 +0100 @@ -157,7 +157,7 @@ Env lintEnv = localEnv; while (lintEnv.info.lint == null) lintEnv = lintEnv.next; - localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags()); + localEnv.info.lint = lintEnv.info.lint.augment(sym.annotations, sym.flags()); return localEnv; } diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Aug 31 10:37:46 2012 +0100 @@ -406,7 +406,7 @@ Lint lintPrev = lint; pendingExits = new ListBuffer(); - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // process all the static initializers @@ -442,7 +442,7 @@ if (tree.body == null) return; Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -468,7 +468,7 @@ public void visitVarDef(JCVariableDecl tree) { if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scan(tree.init); } finally { @@ -783,7 +783,7 @@ } classDef = tree; thrown = List.nil(); - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // process all the static initializers @@ -863,7 +863,7 @@ List mthrown = tree.sym.type.getThrownTypes(); Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -902,7 +902,7 @@ public void visitVarDef(JCVariableDecl tree) { if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scan(tree.init); } finally { @@ -1491,7 +1491,7 @@ firstadr = nextadr; } classDef = tree; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try { // define all the static fields @@ -1558,7 +1558,7 @@ int firstadrPrev = firstadr; Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); Assert.check(pendingExits.isEmpty()); @@ -1609,7 +1609,7 @@ if (track && tree.sym.owner.kind == MTH) newVar(tree.sym); if (tree.init != null) { Lint lintPrev = lint; - lint = lint.augment(tree.sym.attributes_field); + lint = lint.augment(tree.sym.annotations); try{ scanExpr(tree.init); if (track) letInit(tree.pos(), tree.sym); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Aug 31 10:37:46 2012 +0100 @@ -2257,7 +2257,7 @@ null, List.nil(), List.nil()); ClassSymbol c = tree.packge.package_info; c.flags_field |= flags; - c.attributes_field = tree.packge.attributes_field; + c.annotations.setAttributes(tree.packge.annotations); ClassType ctype = (ClassType) c.type; ctype.supertype_field = syms.objectType; ctype.interfaces_field = List.nil(); @@ -2274,7 +2274,8 @@ case LEGACY: return tree.packageAnnotations.nonEmpty(); case NONEMPTY: - for (Attribute.Compound a: tree.packge.attributes_field) { + for (Attribute.Compound a : + tree.packge.annotations.getAttributes()) { Attribute.RetentionPolicy p = types.getRetention(a); if (p != Attribute.RetentionPolicy.SOURCE) return true; diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Aug 31 10:37:46 2012 +0100 @@ -76,11 +76,10 @@ private final Annotate annotate; private final Types types; private final JCDiagnostic.Factory diags; + private final Source source; private final Target target; private final DeferredLintHandler deferredLintHandler; - private final boolean skipAnnotations; - public static MemberEnter instance(Context context) { MemberEnter instance = context.get(memberEnterKey); if (instance == null) @@ -102,10 +101,9 @@ annotate = Annotate.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); + source = Source.instance(context); target = Target.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); - Options options = Options.instance(context); - skipAnnotations = options.isSet("skipAnnotations"); } /** A queue for classes whose members still need to be entered into the @@ -690,7 +688,7 @@ public Env getMethodEnv(JCMethodDecl tree, Env env) { Env mEnv = methodEnv(tree, env); - mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags()); + mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags()); for (List l = tree.typarams; l.nonEmpty(); l = l.tail) mEnv.info.scope.enterIfAbsent(l.head.type.tsym); for (List l = tree.params; l.nonEmpty(); l = l.tail) @@ -727,18 +725,24 @@ void annotateLater(final List annotations, final Env localEnv, final Symbol s) { - if (annotations.isEmpty()) return; - if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now - annotate.later(new Annotate.Annotator() { + if (annotations.isEmpty()) { + return; + } + if (s.kind != PCK) { + s.annotations.reset(); // mark Annotations as incomplete for now + } + annotate.normal(new Annotate.Annotator() { + @Override public String toString() { return "annotate " + annotations + " onto " + s + " in " + s.owner; } + + @Override public void enterAnnotation() { - Assert.check(s.kind == PCK || s.attributes_field == null); + Assert.check(s.kind == PCK || s.annotations.pendingCompletion()); JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { - if (s.attributes_field != null && - s.attributes_field.nonEmpty() && + if (!s.annotations.isEmpty() && annotations.nonEmpty()) log.error(annotations.head.pos, "already.annotated", @@ -756,7 +760,7 @@ * java.lang.Deprecated. **/ private boolean hasDeprecatedAnnotation(List annotations) { - for (List al = annotations; al.nonEmpty(); al = al.tail) { + for (List al = annotations; !al.isEmpty(); al = al.tail) { JCAnnotation a = al.head; if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty()) return true; @@ -764,42 +768,62 @@ return false; } - /** Enter a set of annotations. */ private void enterAnnotations(List annotations, Env env, Symbol s) { - ListBuffer buf = - new ListBuffer(); - Set annotated = new HashSet(); - if (!skipAnnotations) - for (List al = annotations; al.nonEmpty(); al = al.tail) { + Map> annotated = + new LinkedHashMap>(); + Map pos = + new HashMap(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { JCAnnotation a = al.head; Attribute.Compound c = annotate.enterAnnotation(a, syms.annotationType, env); - if (c == null) continue; - buf.append(c); + if (c == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (source.allowRepeatedAnnotations()) { + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(c); + annotated.put(a.type.tsym, l); + pos.put(c, a.pos()); + } else { + log.error(a.pos(), "duplicate.annotation"); + } + } else { + annotated.put(a.type.tsym, ListBuffer.of(c)); + pos.put(c, a.pos()); + } + // Note: @Deprecated has no effect on local variables and parameters if (!c.type.isErroneous() && s.owner.kind != MTH - && types.isSameType(c.type, syms.deprecatedType)) + && types.isSameType(c.type, syms.deprecatedType)) { s.flags_field |= Flags.DEPRECATED; - if (!annotated.add(a.type.tsym)) - log.error(a.pos, "duplicate.annotation"); + } } - s.attributes_field = buf.toList(); + + s.annotations.setAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log)); } /** Queue processing of an attribute default value. */ void annotateDefaultValueLater(final JCExpression defaultValue, final Env localEnv, final MethodSymbol m) { - annotate.later(new Annotate.Annotator() { + annotate.normal(new Annotate.Annotator() { + @Override public String toString() { return "annotate " + m.owner + "." + m + " default " + defaultValue; } + + @Override public void enterAnnotation() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Aug 31 10:37:46 2012 +0100 @@ -1321,7 +1321,7 @@ else proxies.append(proxy); } - annotate.later(new AnnotationCompleter(sym, proxies.toList())); + annotate.normal(new AnnotationCompleter(sym, proxies.toList())); } } @@ -1347,7 +1347,7 @@ void attachAnnotationDefault(final Symbol sym) { final MethodSymbol meth = (MethodSymbol)sym; // only on methods final Attribute value = readAttributeValue(); - annotate.later(new AnnotationDefaultCompleter(meth, value)); + annotate.normal(new AnnotationDefaultCompleter(meth, value)); } Type readTypeOrClassSymbol(int i) { @@ -1693,10 +1693,13 @@ JavaFileObject previousClassFile = currentClassFile; try { currentClassFile = classFile; + Annotations annotations = sym.annotations; List newList = deproxyCompoundList(l); - sym.attributes_field = ((sym.attributes_field == null) - ? newList - : newList.prependList(sym.attributes_field)); + if (annotations.pendingCompletion()) { + annotations.setAttributes(newList); + } else { + annotations.append(newList); + } } finally { currentClassFile = previousClassFile; } diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Aug 31 10:37:46 2012 +0100 @@ -825,7 +825,7 @@ } public void visitClass(Attribute.Class clazz) { databuf.appendByte('c'); - databuf.appendChar(pool.put(typeSig(clazz.type))); + databuf.appendChar(pool.put(typeSig(clazz.classType))); } public void visitCompound(Attribute.Compound compound) { databuf.appendByte('@'); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Aug 31 10:37:46 2012 +0100 @@ -157,7 +157,7 @@ if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0) return false; - for (Attribute.Compound a: c.attributes_field) { + for (Attribute.Compound a: c.annotations.getAttributes()) { if (a.type.tsym == syms.nativeHeaderType.tsym) return true; } diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java --- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ } public void visitClass(Attribute.Class c) { - value = new MirroredTypeExceptionProxy(c.type); + value = new MirroredTypeExceptionProxy(c.classType); } public void visitArray(Attribute.Array a) { @@ -187,7 +187,7 @@ // Construct a proxy for a MirroredTypesException ListBuffer elems = new ListBuffer(); for (Attribute value : a.values) { - Type elem = ((Attribute.Class) value).type; + Type elem = ((Attribute.Class) value).classType; elems.append(elem); } value = new MirroredTypesExceptionProxy(elems.toList()); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Aug 31 10:37:46 2012 +0100 @@ -250,6 +250,70 @@ compiler.err.duplicate.annotation.member.value=\ duplicate annotation member value {0} in {1} +# 0: type +compiler.err.duplicate.annotation.missing.container=\ + duplicate annotation, the declaration of {0} does not have a ContainedBy annotation + +# 0: type, 1: type +compiler.err.invalid.container.no.containedby=\ + invalid contained repeatable annotation, {0} is not annotated with {1} + +# 0: type, 1: type +compiler.err.invalid.container.wrong.containedby=\ + invalid contained repeatable annotation, {0} does not match {1} + +# 0: type, 1: type +compiler.err.invalid.container.no.containerfor=\ + invalid container for repeating annotations, {0} is not annotated with {1} + +# 0: type, 1: type +compiler.err.invalid.container.wrong.containerfor=\ + invalid container for repeating annotations, {0} does not match {1} + +# 0: type +compiler.err.invalid.containedby.annotation=\ + duplicate annotation, {0} is annotated with an invalid ContainedBy annotation + +# 0: type +compiler.err.invalid.containedby.annotation.no.value=\ + duplicate annotation, {0} is not a valid ContainedBy, no value element method declared + +# 0: type, 1: number +compiler.err.invalid.containedby.annotation.multiple.values=\ + duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared + +# 0: type +compiler.err.invalid.containedby.annotation.invalid.value=\ + duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method + +# 0: type, 1: type, 2: type +compiler.err.invalid.containedby.annotation.value.return=\ + duplicate annotation, value element of containing annotation {0} should have type {2}, found {1} + +# 0: type, 1: symbol +compiler.err.invalid.containedby.annotation.elem.nondefault=\ + duplicate annotation, element {1} in containing annotation {0} does not have a default value + +# 0: symbol, 1: type, 2: symbol, 3: type +compiler.err.invalid.containedby.annotation.retention=\ + containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3} + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.not.documented=\ + containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.not.inherited=\ + containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is + +# 0: symbol, 1: symbol +compiler.err.invalid.containedby.annotation.incompatible.target=\ + target of container annotation {0} is not a subset of target of repeated annotation {1} + +# 0: symbol +compiler.err.invalid.containedby.annotation.repeated.and.container.present=\ + container {0} must not be present at the same time as the element it contains + # 0: name compiler.err.duplicate.class=\ duplicate class: {0} diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java --- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,9 +206,7 @@ } ClassSymbol cs = (ClassSymbol) sym; if (addLegacyAnnotation) { - cs.attributes_field = (cs.attributes_field == null) - ? List.of(proprietary) - : cs.attributes_field.prepend(proprietary); + cs.annotations.prepend(List.of(proprietary)); } writeClass(pool, cs, writer); } diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -740,7 +740,7 @@ result = Literal(v.value); } public void visitClass(Attribute.Class clazz) { - result = ClassLiteral(clazz.type).setType(syms.classType); + result = ClassLiteral(clazz.classType).setType(syms.classType); } public void visitEnum(Attribute.Enum e) { result = QualIdent(e.value); diff -r bee2d435e11f -r 4d519199a6aa langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,7 @@ public void visitClass(Attribute.Class c) { value = TypeMaker.getType(env, - env.types.erasure(c.type)); + env.types.erasure(c.classType)); } public void visitEnum(Attribute.Enum e) { diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean BasicRepeatingAnnotations BasicRepeatingAnnos BasicNonRepeatingAnno Foo Foos Bar + * @run compile BasicRepeatingAnnotations.java + * @run main BasicRepeatingAnnotations + */ + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Foos.class) +@interface Foo {} + +@ContainerFor(Foo.class) +@Retention(RetentionPolicy.RUNTIME) +@interface Foos { + Foo[] value(); +} + +@interface Bar {} + +@Foo @Foo +@Foo +@Bar +@Foo +@Foo +@Foo +@Foo +@Foo @Foo +@Foo +class BasicRepeatingAnnos {} + +@Foo +class BasicNonRepeatingAnno {} + +public class BasicRepeatingAnnotations { + public static void main(String[] args) throws Exception { + Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + + // verify that container not present on nonrepeating + a = BasicNonRepeatingAnno.class.getAnnotation(Foos.class); + if (a != null) { + throw new RuntimeException("Container annotation present"); + } + a = BasicNonRepeatingAnno.class.getAnnotation(Foo.class); + if (a == null) { + throw new RuntimeException("Repeated annoation not directly present"); + } + } +} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Foos Foo Bars Bar Baz Bazs CheckTargets + * @run compile CheckTargets.java + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@Target(ElementType.TYPE) +@interface Foo {} + +@ContainerFor(Foo.class) +@Target(ElementType.ANNOTATION_TYPE) +@interface Foos { + Foo[] value(); +} + +@ContainedBy(Bars.class) +@Target(ElementType.TYPE) +@interface Bar {} + +@ContainerFor(Bar.class) +@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) +@interface Bars { + Bar[] value(); +} + + +@ContainedBy(Bazs.class) +@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) +@interface Baz {} + +@ContainerFor(Baz.class) +@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) +@interface Bazs { + Baz[] value(); +} + + +public class CheckTargets {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Bar BarContainer ContainerHasRepeatedContained + * @run compile ContainerHasRepeatedContained.java + */ + +import java.lang.annotation.ContainedBy; +import java.lang.annotation.ContainerFor; + +@ContainedBy(BarContainer.class) +@interface Bar {} + +@Bar +@Bar +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} + +public class ContainerHasRepeatedContained {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean DelayRepeatedContainer Bar BarContainer + * @run compile DelayRepeatedContainer.java + */ + +import java.lang.annotation.*; + +public class DelayRepeatedContainer { + @Bar("apa") @Bar("banan") + String meh() { return "meh"; } +} + +@Bar("katt") +@Bar("lol") +@ContainedBy(BarContainer.class) +@interface Bar { + String value(); +} + +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean Foos Foo + * @run compile/fail InvalidTarget.java + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@Target(ElementType.ANNOTATION_TYPE) +@interface Foo {} + +@ContainerFor(Foo.class) +@Target(ElementType.TYPE) +@interface Foos { + Foo[] value(); +} + +public class InvalidTargets {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail MissingContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + + +@ContainerFor(MissingContainedBy.class) +@interface Foos { + MissingContainedBy[] value(); +} + +public @interface MissingContainedBy {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail MissingContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@interface Foos { + MissingContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface MissingContainerFor {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean NestedContainers BasicRepeatingAnnos BasicRepeatingAnnos2 Foo Foos FoosFoos + * @run compile NestedContainers.java + * @run main NestedContainers + */ + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Foos.class) +@interface Foo {} + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(FoosFoos.class) +@ContainerFor(Foo.class) +@interface Foos { + Foo[] value(); +} + +@ContainerFor(Foos.class) +@Retention(RetentionPolicy.RUNTIME) +@interface FoosFoos { + Foos[] value(); +} + +@Foo +@Foo +class BasicRepeatingAnnos {} + +@Foos({}) +@Foos({}) +class BasicRepeatingAnnos2 {} + +public class NestedContainers { + public static void main(String[] args) throws Exception { + Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + + // Check 2:nd level container + a = BasicRepeatingAnnos2.class.getAnnotation(FoosFoos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + } +} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean RepMemberAnno Bar BarContainer + * @run compile RepMemberAnno.java + */ + +import java.lang.annotation.ContainedBy; +import java.lang.annotation.ContainerFor; + +public class RepMemberAnno { + @Bar("Apa") @Bar("Banan") + public void meh() {} +} + +@ContainedBy(BarContainer.class) +@interface Bar { + String value(); +} + +@ContainerFor(Bar.class) +@interface BarContainer { + Bar[] value(); +} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean RepSelfMemberAnno BarContainer BarContainerContainer + * @run compile RepSelfMemberAnno.java + */ + +import java.lang.annotation.*; + + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(BarContainer.class) +public @interface RepSelfMemberAnno { + @RepSelfMemberAnno @RepSelfMemberAnno + String meh() default "banan"; +} + + +@ContainedBy(BarContainerContainer.class) +@Retention(RetentionPolicy.RUNTIME) +@ContainerFor(RepSelfMemberAnno.class) +@interface BarContainer { + RepSelfMemberAnno[] value(); +} + +@ContainerFor(BarContainer.class) +@Retention(RetentionPolicy.RUNTIME) +@interface BarContainerContainer { + BarContainer[] value(); + String meh() default "apa"; +} + +@BarContainer(value={}) +@BarContainer(value={}) +@interface Bar {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail RepeatingAndContainerPresent.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@interface Foo {} + +@interface Foos { + Foo[] value(); +} + + +@Foo +@Foo +@Foos({}) +public class RepeatingAndContainerPresent {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @bug 7151010 + * + * @run clean SelfRepeatingAnnotations Foos SelfRepeatingAnno + * @run compile SelfRepeatingAnnotations.java + * @run main SelfRepeatingAnnotations + */ + +import java.lang.annotation.*; + +@ContainerFor(SelfRepeatingAnno.class) +@Retention(RetentionPolicy.RUNTIME) +@interface Foos { + SelfRepeatingAnno[] value(); +} + +@SelfRepeatingAnno +@Retention(RetentionPolicy.RUNTIME) +@SelfRepeatingAnno +@ContainedBy(Foos.class) +@interface SelfRepeatingAnno {} + +public class SelfRepeatingAnnotations { + public static void main(String[] args) throws Exception { + Annotation a = SelfRepeatingAnno.class.getAnnotation(Foos.class); + if (a == null) { + throw new RuntimeException("Container annotation missing"); + } + } +} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile SingleRepeatingAndContainer.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainedBy(Foos.class) +@interface Foo {} + +@ContainerFor(Foo.class) +@interface Foos { + Foo[] value(); +} + +@Foo +@Foos({}) +public class SingleRepeatingAndContainer {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail UseWrongContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(UseWrongContainedBy.class) +@interface Foos { + UseWrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface UseWrongContainedBy {} + +@UseWrongContainedBy @UseWrongContainedBy +@interface Foo {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail UseWrongContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + UseWrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface UseWrongContainerFor {} + +@UseWrongContainerFor @UseWrongContainerFor +@interface Foo {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail WrongContainedBy.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(WrongContainedBy.class) +@interface Foos { + WrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface WrongContainedBy {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Smoke test for repeating annotations + * @compile/fail WrongContainerFor.java + * @bug 7151010 + */ + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + WrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface WrongContainerFor {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples.not-yet.txt --- a/langtools/test/tools/javac/diags/examples.not-yet.txt Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Aug 31 10:37:46 2012 +0100 @@ -5,6 +5,9 @@ compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.illegal.char.for.encoding +compiler.err.invalid.containedby.annotation # should not happen +compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen +compiler.err.invalid.containedby.annotation.multiple.values # can't happen compiler.err.io.exception # (javah.JavahTask?) compiler.err.limit.code # Code compiler.err.limit.code.too.large.for.try.stmt # Gen diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.not.documented + +import java.lang.annotation.*; + +@Documented +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByDocumentedMismatch { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.not.inherited + +import java.lang.annotation.*; + +@Inherited +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByInheritedMismatch { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByNoValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.no.value + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos {} + +@Anno +@Anno +class ContainedByNoValue { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.elem.nondefault + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); String foo(); } + +@Anno +@Anno +class ContainedByNonDefault { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.retention + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +class ContainedByRetentionMismatch { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.incompatible.target + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@Target(ElementType.METHOD) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +class ContainedByTargetMismatch { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.value.return + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { String value(); } + +@Anno +@Anno +class ContainedByWrongValueType { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java --- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Mon Aug 27 10:59:13 2012 -0700 +++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Fri Aug 31 10:37:46 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,8 @@ */ // key: compiler.err.duplicate.annotation +// key: compiler.warn.source.no.bootclasspath +// options: -source 7 @interface Anno { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.duplicate.annotation.missing.container + +@interface Anno { } + +@Anno +@Anno +class DuplicateAnnotationJava8 { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present + +import java.lang.annotation.*; + +@ContainedBy(Annos.class) +@interface Anno { } + +@ContainerFor(Anno.class) +@interface Annos { Anno[] value(); } + +@Anno +@Anno +@Annos(@Anno) +class RepeatingAnnotationAndContainer { } diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/WrongContainedBy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.container.no.containerfor +// key: compiler.err.invalid.container.wrong.containedby + +import java.lang.annotation.*; + +@ContainerFor(WrongContainedBy.class) +@interface Foos { + WrongContainedBy[] value(); +} + +@ContainedBy(Target.class) +public @interface WrongContainedBy {} diff -r bee2d435e11f -r 4d519199a6aa langtools/test/tools/javac/diags/examples/WrongContainerFor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java Fri Aug 31 10:37:46 2012 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.invalid.container.wrong.containerfor +// key: compiler.err.invalid.container.no.containedby + +import java.lang.annotation.*; + +@ContainerFor(Retention.class) +@interface Foos { + WrongContainerFor[] value(); +} + +@ContainedBy(Foos.class) +public @interface WrongContainerFor {}