mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 10:04:42 +02:00
7151010: Add compiler support for repeating annotations
Reviewed-by: jjg, mcimadamore
This commit is contained in:
parent
de50ec6f3f
commit
9c23b8bad0
52 changed files with 2284 additions and 95 deletions
|
@ -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().
|
||||
*
|
||||
* <p><b>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.</b>
|
||||
*/
|
||||
public class Annotations {
|
||||
|
||||
private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
|
||||
private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
|
||||
/*
|
||||
* This field should never be null
|
||||
*/
|
||||
private List<Attribute.Compound> attributes = NOT_STARTED;
|
||||
/*
|
||||
* The Symbol this Annotatios belong to
|
||||
*/
|
||||
private final Symbol s;
|
||||
|
||||
public Annotations(Symbol s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public List<Attribute.Compound> getAttributes() {
|
||||
return filterSentinels(attributes);
|
||||
}
|
||||
|
||||
public void setAttributes(List<Attribute.Compound> 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<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
|
||||
boolean atLeastOneRepeated = false;
|
||||
List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
|
||||
for (ListBuffer<Attribute.Compound> 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<Attribute.Compound> 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<Attribute.Compound> l) {
|
||||
attributes = filterSentinels(attributes);
|
||||
|
||||
if (l.isEmpty()) {
|
||||
; // no-op
|
||||
} else if (attributes.isEmpty()) {
|
||||
attributes = l;
|
||||
} else {
|
||||
attributes = attributes.prependList(l);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
|
||||
return (a == IN_PROGRESS || a == NOT_STARTED)
|
||||
? List.<Attribute.Compound>nil()
|
||||
: a;
|
||||
}
|
||||
|
||||
private boolean isStarted() {
|
||||
return attributes != NOT_STARTED;
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> getPlaceholders() {
|
||||
List<Attribute.Compound> res = List.<Attribute.Compound>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<AttrContext> env = ctx.env;
|
||||
JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Attribute.Compound> 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<Attribute.Compound> 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<Attribute.Compound> placeholderFor;
|
||||
private Symbol on;
|
||||
|
||||
public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
|
||||
super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
|
||||
this.placeholderFor = placeholderFor;
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<placeholder: " + placeholderFor + " on: " + on + ">";
|
||||
}
|
||||
|
||||
public List<Attribute.Compound> getPlaceholderFor() {
|
||||
return placeholderFor;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 @@ public abstract class Attribute implements AnnotationValue {
|
|||
* 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 @@ public abstract class Attribute implements AnnotationValue {
|
|||
types.syms.classType.tsym);
|
||||
}
|
||||
public String toString() {
|
||||
return type + ".class";
|
||||
return classType + ".class";
|
||||
}
|
||||
public Type getValue() {
|
||||
return type;
|
||||
return classType;
|
||||
}
|
||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
||||
return v.visitType(type, p);
|
||||
return v.visitType(classType, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,6 +212,12 @@ public abstract class Attribute implements AnnotationValue {
|
|||
super(type);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Array(Type type, List<Attribute> 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();
|
||||
|
|
|
@ -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 @@ public class Lint
|
|||
* Returns the result of combining the values in this object with
|
||||
* the given annotations.
|
||||
*/
|
||||
public Lint augment(List<Attribute.Compound> 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<Attribute.Compound> 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);
|
||||
|
|
|
@ -203,6 +203,9 @@ public enum Source {
|
|||
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:
|
||||
|
|
|
@ -72,22 +72,24 @@ public abstract class Symbol implements Element {
|
|||
*/
|
||||
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<Attribute.Compound> 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<Attribute.Compound> 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 @@ public abstract class Symbol implements Element {
|
|||
this.owner = owner;
|
||||
this.completer = null;
|
||||
this.erasure_field = null;
|
||||
this.attributes_field = List.nil();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
@ -657,10 +658,11 @@ public abstract class Symbol implements Element {
|
|||
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 abstract class Symbol implements Element {
|
|||
|
||||
public List<Attribute.Compound> getAnnotationMirrors() {
|
||||
if (completer != null) complete();
|
||||
return Assert.checkNonNull(attributes_field);
|
||||
return Assert.checkNonNull(annotations.getAttributes());
|
||||
}
|
||||
|
||||
public Type erasure(Types types) {
|
||||
|
|
|
@ -156,6 +156,10 @@ public class Symtab {
|
|||
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 @@ public class Symtab {
|
|||
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,
|
||||
|
|
|
@ -1358,6 +1358,20 @@ public class Types {
|
|||
}
|
||||
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);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="asSuper">
|
||||
|
@ -3811,8 +3825,12 @@ public class Types {
|
|||
// <editor-fold defaultstate="collapsed" desc="Annotation support">
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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 @@ public class Annotate {
|
|||
private int enterCount = 0;
|
||||
|
||||
ListBuffer<Annotator> q = new ListBuffer<Annotator>();
|
||||
ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
|
||||
|
||||
public void later(Annotator a) {
|
||||
public void normal(Annotator a) {
|
||||
q.append(a);
|
||||
}
|
||||
|
||||
|
@ -92,6 +97,10 @@ public class Annotate {
|
|||
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 @@ public class Annotate {
|
|||
try {
|
||||
while (q.nonEmpty())
|
||||
q.next().enterAnnotation();
|
||||
|
||||
while (repeatedQ.nonEmpty()) {
|
||||
repeatedQ.next().enterAnnotation();
|
||||
}
|
||||
} finally {
|
||||
enterCount--;
|
||||
}
|
||||
|
@ -124,6 +137,53 @@ public class Annotate {
|
|||
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<AttrContext> env;
|
||||
public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
|
||||
public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
|
||||
public final Log log;
|
||||
|
||||
public AnnotateRepeatedContext(Env<AttrContext> env,
|
||||
Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
|
||||
Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> 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<Attribute.Compound> 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 @@ public class Annotate {
|
|||
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<Attribute.Compound> annotations,
|
||||
AnnotateRepeatedContext ctx) {
|
||||
Attribute.Compound firstOccurrence = annotations.head;
|
||||
List<Attribute> 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<Attribute.Compound> 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<MethodSymbol, Attribute> p =
|
||||
new Pair<MethodSymbol, Attribute>(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<MethodSymbol,Attribute> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -662,10 +662,12 @@ public class Attr extends JCTree.Visitor {
|
|||
// 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 class Attr extends JCTree.Visitor {
|
|||
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 @@ public class Attr extends JCTree.Visitor {
|
|||
}
|
||||
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
|||
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 @@ public class Attr extends JCTree.Visitor {
|
|||
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 @@ public class Attr extends JCTree.Visitor {
|
|||
}
|
||||
}
|
||||
// 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<JCAnnotation> 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 {
|
||||
|
|
|
@ -69,7 +69,6 @@ public class Check {
|
|||
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 @@ public class Check {
|
|||
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 @@ public class Check {
|
|||
/** Check the annotations of a symbol.
|
||||
*/
|
||||
public void validateAnnotations(List<JCAnnotation> 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 @@ public class Check {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Pair<MethodSymbol,Attribute>> 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<Pair<MethodSymbol,Attribute>> 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<Pair<MethodSymbol,Attribute>> 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<Pair<MethodSymbol,Attribute>> 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<Name> containerTargets = new HashSet<Name>();
|
||||
for (Attribute app : containerTarget.values) {
|
||||
if (!(app instanceof Attribute.Enum)) {
|
||||
continue; // recovery
|
||||
}
|
||||
Attribute.Enum e = (Attribute.Enum)app;
|
||||
containerTargets.add(e.value.name);
|
||||
}
|
||||
|
||||
Set<Name> containedTargets = new HashSet<Name>();
|
||||
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<Name> s, Set<Name> 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 @@ public class Check {
|
|||
|
||||
/** 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 @@ public class Check {
|
|||
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) {
|
||||
|
|
|
@ -157,7 +157,7 @@ public class Enter extends JCTree.Visitor {
|
|||
Env<AttrContext> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -406,7 +406,7 @@ public class Flow {
|
|||
Lint lintPrev = lint;
|
||||
|
||||
pendingExits = new ListBuffer<PendingExit>();
|
||||
lint = lint.augment(tree.sym.attributes_field);
|
||||
lint = lint.augment(tree.sym.annotations);
|
||||
|
||||
try {
|
||||
// process all the static initializers
|
||||
|
@ -442,7 +442,7 @@ public class Flow {
|
|||
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 class Flow {
|
|||
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 @@ public class Flow {
|
|||
}
|
||||
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 @@ public class Flow {
|
|||
List<Type> 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 class Flow {
|
|||
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 @@ public class Flow {
|
|||
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 @@ public class Flow {
|
|||
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 @@ public class Flow {
|
|||
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);
|
||||
|
|
|
@ -2257,7 +2257,7 @@ public class Lower extends TreeTranslator {
|
|||
null, List.<JCExpression>nil(), List.<JCTree>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 @@ public class Lower extends TreeTranslator {
|
|||
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;
|
||||
|
|
|
@ -76,11 +76,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
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 class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
|
||||
public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
|
||||
Env<AttrContext> 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<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
|
||||
mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
|
||||
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
|
||||
|
@ -727,18 +725,24 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
void annotateLater(final List<JCAnnotation> annotations,
|
||||
final Env<AttrContext> 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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
* java.lang.Deprecated.
|
||||
**/
|
||||
private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
|
||||
for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
|
||||
for (List<JCAnnotation> 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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Enter a set of annotations. */
|
||||
private void enterAnnotations(List<JCAnnotation> annotations,
|
||||
Env<AttrContext> env,
|
||||
Symbol s) {
|
||||
ListBuffer<Attribute.Compound> buf =
|
||||
new ListBuffer<Attribute.Compound>();
|
||||
Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
|
||||
if (!skipAnnotations)
|
||||
for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
|
||||
Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
|
||||
new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
|
||||
Map<Attribute.Compound, DiagnosticPosition> pos =
|
||||
new HashMap<Attribute.Compound, DiagnosticPosition>();
|
||||
|
||||
for (List<JCAnnotation> 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<Attribute.Compound> 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<AttrContext> 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 {
|
||||
|
|
|
@ -1321,7 +1321,7 @@ public class ClassReader implements Completer {
|
|||
else
|
||||
proxies.append(proxy);
|
||||
}
|
||||
annotate.later(new AnnotationCompleter(sym, proxies.toList()));
|
||||
annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1347,7 +1347,7 @@ public class ClassReader implements Completer {
|
|||
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 @@ public class ClassReader implements Completer {
|
|||
JavaFileObject previousClassFile = currentClassFile;
|
||||
try {
|
||||
currentClassFile = classFile;
|
||||
Annotations annotations = sym.annotations;
|
||||
List<Attribute.Compound> 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;
|
||||
}
|
||||
|
|
|
@ -825,7 +825,7 @@ public class ClassWriter extends ClassFile {
|
|||
}
|
||||
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('@');
|
||||
|
|
|
@ -157,7 +157,7 @@ public class JNIWriter {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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 class AnnotationProxyMaker {
|
|||
}
|
||||
|
||||
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 @@ public class AnnotationProxyMaker {
|
|||
// Construct a proxy for a MirroredTypesException
|
||||
ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
|
||||
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());
|
||||
|
|
|
@ -250,6 +250,70 @@ compiler.err.duplicate.annotation=\
|
|||
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}
|
||||
|
|
|
@ -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 @@ public class CreateSymbols extends AbstractProcessor {
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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 @@ public class TreeMaker implements JCTree.Factory {
|
|||
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);
|
||||
|
|
|
@ -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 class AnnotationValueImpl implements AnnotationValue {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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();
|
||||
}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -5,6 +5,9 @@ compiler.err.cant.apply.symbol
|
|||
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
|
||||
|
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 { }
|
||||
|
||||
|
|
|
@ -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 { }
|
|
@ -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 { }
|
|
@ -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 {}
|
|
@ -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 {}
|
Loading…
Add table
Add a link
Reference in a new issue