mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.
|
* represented as a ClassSymbol.
|
||||||
*/
|
*/
|
||||||
public static class Class extends Attribute {
|
public static class Class extends Attribute {
|
||||||
public final Type type;
|
public final Type classType;
|
||||||
public void accept(Visitor v) { v.visitClass(this); }
|
public void accept(Visitor v) { v.visitClass(this); }
|
||||||
public Class(Types types, Type type) {
|
public Class(Types types, Type type) {
|
||||||
super(makeClassType(types, type));
|
super(makeClassType(types, type));
|
||||||
this.type = type;
|
this.classType = type;
|
||||||
}
|
}
|
||||||
static Type makeClassType(Types types, Type type) {
|
static Type makeClassType(Types types, Type type) {
|
||||||
Type arg = type.isPrimitive()
|
Type arg = type.isPrimitive()
|
||||||
|
@ -118,13 +118,13 @@ public abstract class Attribute implements AnnotationValue {
|
||||||
types.syms.classType.tsym);
|
types.syms.classType.tsym);
|
||||||
}
|
}
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return type + ".class";
|
return classType + ".class";
|
||||||
}
|
}
|
||||||
public Type getValue() {
|
public Type getValue() {
|
||||||
return type;
|
return classType;
|
||||||
}
|
}
|
||||||
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
|
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);
|
super(type);
|
||||||
this.values = values;
|
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 void accept(Visitor v) { v.visitArray(this); }
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder();
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* Returns the result of combining the values in this object with
|
||||||
* the given annotations.
|
* the given annotations.
|
||||||
*/
|
*/
|
||||||
public Lint augment(List<Attribute.Compound> attrs) {
|
public Lint augment(Annotations annots) {
|
||||||
return augmentor.augment(this, attrs);
|
return augmentor.augment(this, annots.getAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the result of combining the values in this object with
|
* Returns the result of combining the values in this object with
|
||||||
* the given annotations and flags.
|
* the given annotations and flags.
|
||||||
*/
|
*/
|
||||||
public Lint augment(List<Attribute.Compound> attrs, long flags) {
|
public Lint augment(Annotations annots, long flags) {
|
||||||
Lint l = augmentor.augment(this, attrs);
|
Lint l = augmentor.augment(this, annots.getAttributes());
|
||||||
if ((flags & DEPRECATED) != 0) {
|
if ((flags & DEPRECATED) != 0) {
|
||||||
if (l == this)
|
if (l == this)
|
||||||
l = new Lint(this);
|
l = new Lint(this);
|
||||||
|
|
|
@ -203,6 +203,9 @@ public enum Source {
|
||||||
public boolean allowEffectivelyFinalInInnerClasses() {
|
public boolean allowEffectivelyFinalInInnerClasses() {
|
||||||
return compareTo(JDK1_8) >= 0;
|
return compareTo(JDK1_8) >= 0;
|
||||||
}
|
}
|
||||||
|
public boolean allowRepeatedAnnotations() {
|
||||||
|
return compareTo(JDK1_8) >= 0;
|
||||||
|
}
|
||||||
public static SourceVersion toSourceVersion(Source source) {
|
public static SourceVersion toSourceVersion(Source source) {
|
||||||
switch(source) {
|
switch(source) {
|
||||||
case JDK1_2:
|
case JDK1_2:
|
||||||
|
|
|
@ -72,22 +72,24 @@ public abstract class Symbol implements Element {
|
||||||
*/
|
*/
|
||||||
public long flags() { return flags_field; }
|
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.
|
/** An accessor method for the attributes of this symbol.
|
||||||
* Attributes of class symbols should be accessed through the accessor
|
* Attributes of class symbols should be accessed through the accessor
|
||||||
* method to make sure that the class symbol is loaded.
|
* method to make sure that the class symbol is loaded.
|
||||||
*/
|
*/
|
||||||
public List<Attribute.Compound> getAnnotationMirrors() {
|
public List<Attribute.Compound> getAnnotationMirrors() {
|
||||||
return Assert.checkNonNull(attributes_field);
|
return Assert.checkNonNull(annotations.getAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch a particular annotation from a symbol. */
|
/** Fetch a particular annotation from a symbol. */
|
||||||
public Attribute.Compound attribute(Symbol anno) {
|
public Attribute.Compound attribute(Symbol anno) {
|
||||||
for (Attribute.Compound a : getAnnotationMirrors())
|
for (Attribute.Compound a : getAnnotationMirrors()) {
|
||||||
if (a.type.tsym == anno) return a;
|
if (a.type.tsym == anno) return a;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +122,6 @@ public abstract class Symbol implements Element {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.completer = null;
|
this.completer = null;
|
||||||
this.erasure_field = null;
|
this.erasure_field = null;
|
||||||
this.attributes_field = List.nil();
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,10 +658,11 @@ public abstract class Symbol implements Element {
|
||||||
if (completer != null) complete();
|
if (completer != null) complete();
|
||||||
if (package_info != null && package_info.completer != null) {
|
if (package_info != null && package_info.completer != null) {
|
||||||
package_info.complete();
|
package_info.complete();
|
||||||
if (attributes_field.isEmpty())
|
if (annotations.isEmpty()) {
|
||||||
attributes_field = package_info.attributes_field;
|
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
|
/** 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() {
|
public List<Attribute.Compound> getAnnotationMirrors() {
|
||||||
if (completer != null) complete();
|
if (completer != null) complete();
|
||||||
return Assert.checkNonNull(attributes_field);
|
return Assert.checkNonNull(annotations.getAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type erasure(Types types) {
|
public Type erasure(Types types) {
|
||||||
|
|
|
@ -156,6 +156,10 @@ public class Symtab {
|
||||||
public final Type systemType;
|
public final Type systemType;
|
||||||
public final Type autoCloseableType;
|
public final Type autoCloseableType;
|
||||||
public final Type trustMeType;
|
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.
|
/** The symbol representing the length field of an array.
|
||||||
*/
|
*/
|
||||||
|
@ -468,6 +472,10 @@ public class Symtab {
|
||||||
deprecatedType = enterClass("java.lang.Deprecated");
|
deprecatedType = enterClass("java.lang.Deprecated");
|
||||||
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
|
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
|
||||||
inheritedType = enterClass("java.lang.annotation.Inherited");
|
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");
|
systemType = enterClass("java.lang.System");
|
||||||
autoCloseableType = enterClass("java.lang.AutoCloseable");
|
autoCloseableType = enterClass("java.lang.AutoCloseable");
|
||||||
autoCloseableClose = new MethodSymbol(PUBLIC,
|
autoCloseableClose = new MethodSymbol(PUBLIC,
|
||||||
|
|
|
@ -1358,6 +1358,20 @@ public class Types {
|
||||||
}
|
}
|
||||||
return result;
|
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>
|
||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="asSuper">
|
// <editor-fold defaultstate="collapsed" desc="asSuper">
|
||||||
|
@ -3811,8 +3825,12 @@ public class Types {
|
||||||
// <editor-fold defaultstate="collapsed" desc="Annotation support">
|
// <editor-fold defaultstate="collapsed" desc="Annotation support">
|
||||||
|
|
||||||
public RetentionPolicy getRetention(Attribute.Compound a) {
|
public RetentionPolicy getRetention(Attribute.Compound a) {
|
||||||
|
return getRetention(a.type.tsym);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RetentionPolicy getRetention(Symbol sym) {
|
||||||
RetentionPolicy vis = RetentionPolicy.CLASS; // the default
|
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) {
|
if (c != null) {
|
||||||
Attribute value = c.member(names.value);
|
Attribute value = c.member(names.value);
|
||||||
if (value != null && value instanceof Attribute.Enum) {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,7 +25,11 @@
|
||||||
|
|
||||||
package com.sun.tools.javac.comp;
|
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.*;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.tree.*;
|
import com.sun.tools.javac.tree.*;
|
||||||
|
@ -83,8 +87,9 @@ public class Annotate {
|
||||||
private int enterCount = 0;
|
private int enterCount = 0;
|
||||||
|
|
||||||
ListBuffer<Annotator> q = new ListBuffer<Annotator>();
|
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);
|
q.append(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +97,10 @@ public class Annotate {
|
||||||
q.prepend(a);
|
q.prepend(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void repeated(Annotator a) {
|
||||||
|
repeatedQ.append(a);
|
||||||
|
}
|
||||||
|
|
||||||
/** Called when the Enter phase starts. */
|
/** Called when the Enter phase starts. */
|
||||||
public void enterStart() {
|
public void enterStart() {
|
||||||
enterCount++;
|
enterCount++;
|
||||||
|
@ -109,6 +118,10 @@ public class Annotate {
|
||||||
try {
|
try {
|
||||||
while (q.nonEmpty())
|
while (q.nonEmpty())
|
||||||
q.next().enterAnnotation();
|
q.next().enterAnnotation();
|
||||||
|
|
||||||
|
while (repeatedQ.nonEmpty()) {
|
||||||
|
repeatedQ.next().enterAnnotation();
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
enterCount--;
|
enterCount--;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +137,53 @@ public class Annotate {
|
||||||
String toString();
|
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.
|
* Compute an attribute from its annotation.
|
||||||
|
@ -268,4 +328,219 @@ public class Annotate {
|
||||||
log.error(tree.pos(), "annotation.value.not.allowable.type");
|
log.error(tree.pos(), "annotation.value.not.allowable.type");
|
||||||
return new Attribute.Error(attr.attribExpr(tree, env, expected));
|
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
|
// 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
|
// 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.
|
// 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;
|
env.info.lint = lintEnv.info.lint;
|
||||||
else
|
} else {
|
||||||
env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
|
env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations,
|
||||||
|
env.info.enclVar.flags());
|
||||||
|
}
|
||||||
|
|
||||||
Lint prevLint = chk.setLint(env.info.lint);
|
Lint prevLint = chk.setLint(env.info.lint);
|
||||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||||
|
@ -776,7 +778,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
public void visitMethodDef(JCMethodDecl tree) {
|
public void visitMethodDef(JCMethodDecl tree) {
|
||||||
MethodSymbol m = tree.sym;
|
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);
|
Lint prevLint = chk.setLint(lint);
|
||||||
MethodSymbol prevMethod = chk.setMethod(m);
|
MethodSymbol prevMethod = chk.setMethod(m);
|
||||||
try {
|
try {
|
||||||
|
@ -921,7 +923,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
VarSymbol v = tree.sym;
|
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);
|
Lint prevLint = chk.setLint(lint);
|
||||||
|
|
||||||
// Check that the variable's declared type is well-formed.
|
// Check that the variable's declared type is well-formed.
|
||||||
|
@ -3069,7 +3071,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
lintEnv = lintEnv.next;
|
lintEnv = lintEnv.next;
|
||||||
|
|
||||||
// Having found the enclosing lint value, we can initialize the lint value for this class
|
// 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);
|
Lint prevLint = chk.setLint(env.info.lint);
|
||||||
JavaFileObject prev = log.useSource(c.sourcefile);
|
JavaFileObject prev = log.useSource(c.sourcefile);
|
||||||
|
@ -3133,6 +3135,26 @@ public class Attr extends JCTree.Visitor {
|
||||||
if (tree.typarams.nonEmpty())
|
if (tree.typarams.nonEmpty())
|
||||||
log.error(tree.typarams.head.pos(),
|
log.error(tree.typarams.head.pos(),
|
||||||
"intf.annotation.cant.have.type.params");
|
"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 {
|
} else {
|
||||||
// Check that all extended classes and interfaces
|
// Check that all extended classes and interfaces
|
||||||
// are compatible (i.e. no two define methods with same arguments
|
// are compatible (i.e. no two define methods with same arguments
|
||||||
|
@ -3194,6 +3216,16 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// where
|
// 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. */
|
/** check if a class is a subtype of Serializable, if that is available. */
|
||||||
private boolean isSerializable(ClassSymbol c) {
|
private boolean isSerializable(ClassSymbol c) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -69,7 +69,6 @@ public class Check {
|
||||||
private final Infer infer;
|
private final Infer infer;
|
||||||
private final Types types;
|
private final Types types;
|
||||||
private final JCDiagnostic.Factory diags;
|
private final JCDiagnostic.Factory diags;
|
||||||
private final boolean skipAnnotations;
|
|
||||||
private boolean warnOnSyntheticConflicts;
|
private boolean warnOnSyntheticConflicts;
|
||||||
private boolean suppressAbortOnBadClassFile;
|
private boolean suppressAbortOnBadClassFile;
|
||||||
private boolean enableSunApiLintControl;
|
private boolean enableSunApiLintControl;
|
||||||
|
@ -113,7 +112,6 @@ public class Check {
|
||||||
allowCovariantReturns = source.allowCovariantReturns();
|
allowCovariantReturns = source.allowCovariantReturns();
|
||||||
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
|
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
|
||||||
complexInference = options.isSet("complexinference");
|
complexInference = options.isSet("complexinference");
|
||||||
skipAnnotations = options.isSet("skipAnnotations");
|
|
||||||
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
|
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
|
||||||
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
|
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
|
||||||
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
|
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
|
||||||
|
@ -2422,14 +2420,13 @@ public class Check {
|
||||||
/** Check the annotations of a symbol.
|
/** Check the annotations of a symbol.
|
||||||
*/
|
*/
|
||||||
public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
|
public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
|
||||||
if (skipAnnotations) return;
|
|
||||||
for (JCAnnotation a : annotations)
|
for (JCAnnotation a : annotations)
|
||||||
validateAnnotation(a, s);
|
validateAnnotation(a, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check an annotation of a symbol.
|
/** Check an annotation of a symbol.
|
||||||
*/
|
*/
|
||||||
public void validateAnnotation(JCAnnotation a, Symbol s) {
|
private void validateAnnotation(JCAnnotation a, Symbol s) {
|
||||||
validateAnnotationTree(a);
|
validateAnnotationTree(a);
|
||||||
|
|
||||||
if (!annotationApplicable(a, s))
|
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? */
|
/** Is s a method symbol that overrides a method in a superclass? */
|
||||||
boolean isOverrider(Symbol s) {
|
boolean isOverrider(Symbol s) {
|
||||||
if (s.kind != MTH || s.isStatic())
|
if (s.kind != MTH || s.isStatic())
|
||||||
|
@ -2461,12 +2667,10 @@ public class Check {
|
||||||
|
|
||||||
/** Is the annotation applicable to the symbol? */
|
/** Is the annotation applicable to the symbol? */
|
||||||
boolean annotationApplicable(JCAnnotation a, Symbol s) {
|
boolean annotationApplicable(JCAnnotation a, Symbol s) {
|
||||||
Attribute.Compound atTarget =
|
Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
|
||||||
a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
|
if (arr == null) {
|
||||||
if (atTarget == null) return true;
|
return true;
|
||||||
Attribute atValue = atTarget.member(names.value);
|
}
|
||||||
if (!(atValue instanceof Attribute.Array)) return true; // error recovery
|
|
||||||
Attribute.Array arr = (Attribute.Array) atValue;
|
|
||||||
for (Attribute app : arr.values) {
|
for (Attribute app : arr.values) {
|
||||||
if (!(app instanceof Attribute.Enum)) return true; // recovery
|
if (!(app instanceof Attribute.Enum)) return true; // recovery
|
||||||
Attribute.Enum e = (Attribute.Enum) app;
|
Attribute.Enum e = (Attribute.Enum) app;
|
||||||
|
@ -2508,6 +2712,16 @@ public class Check {
|
||||||
return false;
|
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.
|
/** Check an annotation value.
|
||||||
*/
|
*/
|
||||||
public void validateAnnotation(JCAnnotation a) {
|
public void validateAnnotation(JCAnnotation a) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class Enter extends JCTree.Visitor {
|
||||||
Env<AttrContext> lintEnv = localEnv;
|
Env<AttrContext> lintEnv = localEnv;
|
||||||
while (lintEnv.info.lint == null)
|
while (lintEnv.info.lint == null)
|
||||||
lintEnv = lintEnv.next;
|
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;
|
return localEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -406,7 +406,7 @@ public class Flow {
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
|
|
||||||
pendingExits = new ListBuffer<PendingExit>();
|
pendingExits = new ListBuffer<PendingExit>();
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// process all the static initializers
|
// process all the static initializers
|
||||||
|
@ -442,7 +442,7 @@ public class Flow {
|
||||||
if (tree.body == null) return;
|
if (tree.body == null) return;
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
|
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
Assert.check(pendingExits.isEmpty());
|
Assert.check(pendingExits.isEmpty());
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ public class Flow {
|
||||||
public void visitVarDef(JCVariableDecl tree) {
|
public void visitVarDef(JCVariableDecl tree) {
|
||||||
if (tree.init != null) {
|
if (tree.init != null) {
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
try{
|
try{
|
||||||
scan(tree.init);
|
scan(tree.init);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -783,7 +783,7 @@ public class Flow {
|
||||||
}
|
}
|
||||||
classDef = tree;
|
classDef = tree;
|
||||||
thrown = List.nil();
|
thrown = List.nil();
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// process all the static initializers
|
// process all the static initializers
|
||||||
|
@ -863,7 +863,7 @@ public class Flow {
|
||||||
List<Type> mthrown = tree.sym.type.getThrownTypes();
|
List<Type> mthrown = tree.sym.type.getThrownTypes();
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
|
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
Assert.check(pendingExits.isEmpty());
|
Assert.check(pendingExits.isEmpty());
|
||||||
|
|
||||||
|
@ -902,7 +902,7 @@ public class Flow {
|
||||||
public void visitVarDef(JCVariableDecl tree) {
|
public void visitVarDef(JCVariableDecl tree) {
|
||||||
if (tree.init != null) {
|
if (tree.init != null) {
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
try{
|
try{
|
||||||
scan(tree.init);
|
scan(tree.init);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1491,7 +1491,7 @@ public class Flow {
|
||||||
firstadr = nextadr;
|
firstadr = nextadr;
|
||||||
}
|
}
|
||||||
classDef = tree;
|
classDef = tree;
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// define all the static fields
|
// define all the static fields
|
||||||
|
@ -1558,7 +1558,7 @@ public class Flow {
|
||||||
int firstadrPrev = firstadr;
|
int firstadrPrev = firstadr;
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
|
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
|
|
||||||
Assert.check(pendingExits.isEmpty());
|
Assert.check(pendingExits.isEmpty());
|
||||||
|
|
||||||
|
@ -1609,7 +1609,7 @@ public class Flow {
|
||||||
if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
|
if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
|
||||||
if (tree.init != null) {
|
if (tree.init != null) {
|
||||||
Lint lintPrev = lint;
|
Lint lintPrev = lint;
|
||||||
lint = lint.augment(tree.sym.attributes_field);
|
lint = lint.augment(tree.sym.annotations);
|
||||||
try{
|
try{
|
||||||
scanExpr(tree.init);
|
scanExpr(tree.init);
|
||||||
if (track) letInit(tree.pos(), tree.sym);
|
if (track) letInit(tree.pos(), tree.sym);
|
||||||
|
|
|
@ -2257,7 +2257,7 @@ public class Lower extends TreeTranslator {
|
||||||
null, List.<JCExpression>nil(), List.<JCTree>nil());
|
null, List.<JCExpression>nil(), List.<JCTree>nil());
|
||||||
ClassSymbol c = tree.packge.package_info;
|
ClassSymbol c = tree.packge.package_info;
|
||||||
c.flags_field |= flags;
|
c.flags_field |= flags;
|
||||||
c.attributes_field = tree.packge.attributes_field;
|
c.annotations.setAttributes(tree.packge.annotations);
|
||||||
ClassType ctype = (ClassType) c.type;
|
ClassType ctype = (ClassType) c.type;
|
||||||
ctype.supertype_field = syms.objectType;
|
ctype.supertype_field = syms.objectType;
|
||||||
ctype.interfaces_field = List.nil();
|
ctype.interfaces_field = List.nil();
|
||||||
|
@ -2274,7 +2274,8 @@ public class Lower extends TreeTranslator {
|
||||||
case LEGACY:
|
case LEGACY:
|
||||||
return tree.packageAnnotations.nonEmpty();
|
return tree.packageAnnotations.nonEmpty();
|
||||||
case 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);
|
Attribute.RetentionPolicy p = types.getRetention(a);
|
||||||
if (p != Attribute.RetentionPolicy.SOURCE)
|
if (p != Attribute.RetentionPolicy.SOURCE)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -76,11 +76,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
private final Annotate annotate;
|
private final Annotate annotate;
|
||||||
private final Types types;
|
private final Types types;
|
||||||
private final JCDiagnostic.Factory diags;
|
private final JCDiagnostic.Factory diags;
|
||||||
|
private final Source source;
|
||||||
private final Target target;
|
private final Target target;
|
||||||
private final DeferredLintHandler deferredLintHandler;
|
private final DeferredLintHandler deferredLintHandler;
|
||||||
|
|
||||||
private final boolean skipAnnotations;
|
|
||||||
|
|
||||||
public static MemberEnter instance(Context context) {
|
public static MemberEnter instance(Context context) {
|
||||||
MemberEnter instance = context.get(memberEnterKey);
|
MemberEnter instance = context.get(memberEnterKey);
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
|
@ -102,10 +101,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
annotate = Annotate.instance(context);
|
annotate = Annotate.instance(context);
|
||||||
types = Types.instance(context);
|
types = Types.instance(context);
|
||||||
diags = JCDiagnostic.Factory.instance(context);
|
diags = JCDiagnostic.Factory.instance(context);
|
||||||
|
source = Source.instance(context);
|
||||||
target = Target.instance(context);
|
target = Target.instance(context);
|
||||||
deferredLintHandler = DeferredLintHandler.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
|
/** 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) {
|
public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
|
||||||
Env<AttrContext> mEnv = methodEnv(tree, 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)
|
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
|
||||||
mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
|
mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
|
||||||
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
|
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,
|
void annotateLater(final List<JCAnnotation> annotations,
|
||||||
final Env<AttrContext> localEnv,
|
final Env<AttrContext> localEnv,
|
||||||
final Symbol s) {
|
final Symbol s) {
|
||||||
if (annotations.isEmpty()) return;
|
if (annotations.isEmpty()) {
|
||||||
if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
|
return;
|
||||||
annotate.later(new Annotate.Annotator() {
|
}
|
||||||
|
if (s.kind != PCK) {
|
||||||
|
s.annotations.reset(); // mark Annotations as incomplete for now
|
||||||
|
}
|
||||||
|
annotate.normal(new Annotate.Annotator() {
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "annotate " + annotations + " onto " + s + " in " + s.owner;
|
return "annotate " + annotations + " onto " + s + " in " + s.owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void enterAnnotation() {
|
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);
|
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
if (s.attributes_field != null &&
|
if (!s.annotations.isEmpty() &&
|
||||||
s.attributes_field.nonEmpty() &&
|
|
||||||
annotations.nonEmpty())
|
annotations.nonEmpty())
|
||||||
log.error(annotations.head.pos,
|
log.error(annotations.head.pos,
|
||||||
"already.annotated",
|
"already.annotated",
|
||||||
|
@ -756,7 +760,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
* java.lang.Deprecated.
|
* java.lang.Deprecated.
|
||||||
**/
|
**/
|
||||||
private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
|
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;
|
JCAnnotation a = al.head;
|
||||||
if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
|
if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
@ -764,42 +768,62 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Enter a set of annotations. */
|
/** Enter a set of annotations. */
|
||||||
private void enterAnnotations(List<JCAnnotation> annotations,
|
private void enterAnnotations(List<JCAnnotation> annotations,
|
||||||
Env<AttrContext> env,
|
Env<AttrContext> env,
|
||||||
Symbol s) {
|
Symbol s) {
|
||||||
ListBuffer<Attribute.Compound> buf =
|
Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
|
||||||
new ListBuffer<Attribute.Compound>();
|
new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
|
||||||
Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
|
Map<Attribute.Compound, DiagnosticPosition> pos =
|
||||||
if (!skipAnnotations)
|
new HashMap<Attribute.Compound, DiagnosticPosition>();
|
||||||
for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
|
|
||||||
|
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
|
||||||
JCAnnotation a = al.head;
|
JCAnnotation a = al.head;
|
||||||
Attribute.Compound c = annotate.enterAnnotation(a,
|
Attribute.Compound c = annotate.enterAnnotation(a,
|
||||||
syms.annotationType,
|
syms.annotationType,
|
||||||
env);
|
env);
|
||||||
if (c == null) continue;
|
if (c == null) {
|
||||||
buf.append(c);
|
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
|
// Note: @Deprecated has no effect on local variables and parameters
|
||||||
if (!c.type.isErroneous()
|
if (!c.type.isErroneous()
|
||||||
&& s.owner.kind != MTH
|
&& s.owner.kind != MTH
|
||||||
&& types.isSameType(c.type, syms.deprecatedType))
|
&& types.isSameType(c.type, syms.deprecatedType)) {
|
||||||
s.flags_field |= Flags.DEPRECATED;
|
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. */
|
/** Queue processing of an attribute default value. */
|
||||||
void annotateDefaultValueLater(final JCExpression defaultValue,
|
void annotateDefaultValueLater(final JCExpression defaultValue,
|
||||||
final Env<AttrContext> localEnv,
|
final Env<AttrContext> localEnv,
|
||||||
final MethodSymbol m) {
|
final MethodSymbol m) {
|
||||||
annotate.later(new Annotate.Annotator() {
|
annotate.normal(new Annotate.Annotator() {
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "annotate " + m.owner + "." +
|
return "annotate " + m.owner + "." +
|
||||||
m + " default " + defaultValue;
|
m + " default " + defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void enterAnnotation() {
|
public void enterAnnotation() {
|
||||||
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
|
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1321,7 +1321,7 @@ public class ClassReader implements Completer {
|
||||||
else
|
else
|
||||||
proxies.append(proxy);
|
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) {
|
void attachAnnotationDefault(final Symbol sym) {
|
||||||
final MethodSymbol meth = (MethodSymbol)sym; // only on methods
|
final MethodSymbol meth = (MethodSymbol)sym; // only on methods
|
||||||
final Attribute value = readAttributeValue();
|
final Attribute value = readAttributeValue();
|
||||||
annotate.later(new AnnotationDefaultCompleter(meth, value));
|
annotate.normal(new AnnotationDefaultCompleter(meth, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Type readTypeOrClassSymbol(int i) {
|
Type readTypeOrClassSymbol(int i) {
|
||||||
|
@ -1693,10 +1693,13 @@ public class ClassReader implements Completer {
|
||||||
JavaFileObject previousClassFile = currentClassFile;
|
JavaFileObject previousClassFile = currentClassFile;
|
||||||
try {
|
try {
|
||||||
currentClassFile = classFile;
|
currentClassFile = classFile;
|
||||||
|
Annotations annotations = sym.annotations;
|
||||||
List<Attribute.Compound> newList = deproxyCompoundList(l);
|
List<Attribute.Compound> newList = deproxyCompoundList(l);
|
||||||
sym.attributes_field = ((sym.attributes_field == null)
|
if (annotations.pendingCompletion()) {
|
||||||
? newList
|
annotations.setAttributes(newList);
|
||||||
: newList.prependList(sym.attributes_field));
|
} else {
|
||||||
|
annotations.append(newList);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
currentClassFile = previousClassFile;
|
currentClassFile = previousClassFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -825,7 +825,7 @@ public class ClassWriter extends ClassFile {
|
||||||
}
|
}
|
||||||
public void visitClass(Attribute.Class clazz) {
|
public void visitClass(Attribute.Class clazz) {
|
||||||
databuf.appendByte('c');
|
databuf.appendByte('c');
|
||||||
databuf.appendChar(pool.put(typeSig(clazz.type)));
|
databuf.appendChar(pool.put(typeSig(clazz.classType)));
|
||||||
}
|
}
|
||||||
public void visitCompound(Attribute.Compound compound) {
|
public void visitCompound(Attribute.Compound compound) {
|
||||||
databuf.appendByte('@');
|
databuf.appendByte('@');
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class JNIWriter {
|
||||||
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
|
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (Attribute.Compound a: c.attributes_field) {
|
for (Attribute.Compound a: c.annotations.getAttributes()) {
|
||||||
if (a.type.tsym == syms.nativeHeaderType.tsym)
|
if (a.type.tsym == syms.nativeHeaderType.tsym)
|
||||||
return true;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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) {
|
public void visitClass(Attribute.Class c) {
|
||||||
value = new MirroredTypeExceptionProxy(c.type);
|
value = new MirroredTypeExceptionProxy(c.classType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitArray(Attribute.Array a) {
|
public void visitArray(Attribute.Array a) {
|
||||||
|
@ -187,7 +187,7 @@ public class AnnotationProxyMaker {
|
||||||
// Construct a proxy for a MirroredTypesException
|
// Construct a proxy for a MirroredTypesException
|
||||||
ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
|
ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
|
||||||
for (Attribute value : a.values) {
|
for (Attribute value : a.values) {
|
||||||
Type elem = ((Attribute.Class) value).type;
|
Type elem = ((Attribute.Class) value).classType;
|
||||||
elems.append(elem);
|
elems.append(elem);
|
||||||
}
|
}
|
||||||
value = new MirroredTypesExceptionProxy(elems.toList());
|
value = new MirroredTypesExceptionProxy(elems.toList());
|
||||||
|
|
|
@ -250,6 +250,70 @@ compiler.err.duplicate.annotation=\
|
||||||
compiler.err.duplicate.annotation.member.value=\
|
compiler.err.duplicate.annotation.member.value=\
|
||||||
duplicate annotation member value {0} in {1}
|
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
|
# 0: name
|
||||||
compiler.err.duplicate.class=\
|
compiler.err.duplicate.class=\
|
||||||
duplicate class: {0}
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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;
|
ClassSymbol cs = (ClassSymbol) sym;
|
||||||
if (addLegacyAnnotation) {
|
if (addLegacyAnnotation) {
|
||||||
cs.attributes_field = (cs.attributes_field == null)
|
cs.annotations.prepend(List.of(proprietary));
|
||||||
? List.of(proprietary)
|
|
||||||
: cs.attributes_field.prepend(proprietary);
|
|
||||||
}
|
}
|
||||||
writeClass(pool, cs, writer);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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);
|
result = Literal(v.value);
|
||||||
}
|
}
|
||||||
public void visitClass(Attribute.Class clazz) {
|
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) {
|
public void visitEnum(Attribute.Enum e) {
|
||||||
result = QualIdent(e.value);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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) {
|
public void visitClass(Attribute.Class c) {
|
||||||
value = TypeMaker.getType(env,
|
value = TypeMaker.getType(env,
|
||||||
env.types.erasure(c.type));
|
env.types.erasure(c.classType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitEnum(Attribute.Enum e) {
|
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.read.file # (apt.JavaCompiler?)
|
||||||
compiler.err.cant.select.static.class.from.param.type
|
compiler.err.cant.select.static.class.from.param.type
|
||||||
compiler.err.illegal.char.for.encoding
|
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.io.exception # (javah.JavahTask?)
|
||||||
compiler.err.limit.code # Code
|
compiler.err.limit.code # Code
|
||||||
compiler.err.limit.code.too.large.for.try.stmt # Gen
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -22,6 +22,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.duplicate.annotation
|
// key: compiler.err.duplicate.annotation
|
||||||
|
// key: compiler.warn.source.no.bootclasspath
|
||||||
|
// options: -source 7
|
||||||
|
|
||||||
@interface Anno { }
|
@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