8013852: update reference impl for type-annotations
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com, joel.franck@oracle.com, alex.buckley@oracle.com
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Tue May 14 15:04:06 2013 -0700
@@ -751,7 +751,7 @@
break;
// exception parameter
case EXCEPTION_PARAMETER:
- out.writeByte(p.exception_index);
+ out.writeShort(p.exception_index);
break;
// method receiver
case METHOD_RECEIVER:
@@ -770,11 +770,11 @@
break;
// class extends or implements clause
case CLASS_EXTENDS:
- out.writeByte(p.type_index);
+ out.writeShort(p.type_index);
break;
// throws
case THROWS:
- out.writeByte(p.type_index);
+ out.writeShort(p.type_index);
break;
// method parameter
case METHOD_FORMAL_PARAMETER:
--- a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java Tue May 14 15:04:06 2013 -0700
@@ -111,7 +111,7 @@
break;
// exception parameter
case EXCEPTION_PARAMETER:
- position.exception_index = cr.readUnsignedByte();
+ position.exception_index = cr.readUnsignedShort();
break;
// method receiver
case METHOD_RECEIVER:
@@ -198,7 +198,7 @@
break;
// exception parameter
case EXCEPTION_PARAMETER:
- n += 1; // exception_index
+ n += 2; // exception_index
break;
// method receiver
case METHOD_RECEIVER:
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue May 14 15:04:06 2013 -0700
@@ -1726,7 +1726,7 @@
return text;
}
- static Set<String> blockTags = new HashSet<String>();
+ static final Set<String> blockTags = new HashSet<String>();
static {
for (HtmlTag t: HtmlTag.values()) {
if (t.blockType == HtmlTag.BlockType.BLOCK)
@@ -1771,7 +1771,7 @@
return result.toString();
}
- private static final boolean isHtmlTagLetterOrDigit(char ch) {
+ private static boolean isHtmlTagLetterOrDigit(char ch) {
return ('a' <= ch && ch <= 'z') ||
('A' <= ch && ch <= 'Z') ||
('1' <= ch && ch <= '6');
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Tue May 14 15:04:06 2013 -0700
@@ -76,11 +76,24 @@
private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
/*
- * This field should never be null
+ * Type attributes for this symbol.
+ * This field should never be null.
*/
private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
/*
+ * Type attributes of initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * Type attributes of class initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
* The Symbol this Annotations instance belongs to
*/
private final Symbol sym;
@@ -97,6 +110,14 @@
return type_attributes;
}
+ public List<Attribute.TypeCompound> getInitTypeAttributes() {
+ return init_type_attributes;
+ }
+
+ public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
+ return clinit_type_attributes;
+ }
+
public void setDeclarationAttributes(List<Attribute.Compound> a) {
Assert.check(pendingCompletion() || !isStarted());
if (a == null) {
@@ -112,12 +133,28 @@
type_attributes = a;
}
+ public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ init_type_attributes = a;
+ }
+
+ public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ clinit_type_attributes = a;
+ }
+
public void setAttributes(Annotations other) {
if (other == null) {
throw new NullPointerException();
}
setDeclarationAttributes(other.getDeclarationAttributes());
setTypeAttributes(other.getTypeAttributes());
+ setInitTypeAttributes(other.getInitTypeAttributes());
+ setClassInitTypeAttributes(other.getClassInitTypeAttributes());
}
public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
@@ -232,6 +269,28 @@
return this;
}
+ public Annotations appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (init_type_attributes.isEmpty()) {
+ init_type_attributes = l;
+ } else {
+ init_type_attributes = init_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public Annotations appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (clinit_type_attributes.isEmpty()) {
+ clinit_type_attributes = l;
+ } else {
+ clinit_type_attributes = clinit_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
public Annotations prepend(List<Attribute.Compound> l) {
attributes = filterDeclSentinels(attributes);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Tue May 14 15:04:06 2013 -0700
@@ -230,6 +230,42 @@
this.position = position;
}
+ public boolean hasUnknownPosition() {
+ return position == null || position.type == TargetType.UNKNOWN;
+ }
+
+ public boolean isContainerTypeCompound() {
+ if (isSynthesized() && values.size() == 1)
+ return getFirstEmbeddedTC() != null;
+ return false;
+ }
+
+ private TypeCompound getFirstEmbeddedTC() {
+ if (values.size() == 1) {
+ Pair<MethodSymbol, Attribute> val = values.get(0);
+ if (val.fst.getSimpleName().contentEquals("value")
+ && val.snd instanceof Array) {
+ Array arr = (Array) val.snd;
+ if (arr.values.length != 0
+ && arr.values[0] instanceof Attribute.TypeCompound)
+ return (Attribute.TypeCompound) arr.values[0];
+ }
+ }
+ return null;
+ }
+
+ public boolean tryFixPosition() {
+ if (!isContainerTypeCompound())
+ return false;
+
+ TypeCompound from = getFirstEmbeddedTC();
+ if (from != null && from.position != null &&
+ from.position.type != TargetType.UNKNOWN) {
+ position = from.position;
+ return true;
+ }
+ return false;
+ }
}
/** The value for an annotation element of an array type.
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Tue May 14 15:04:06 2013 -0700
@@ -31,6 +31,7 @@
import com.sun.tools.javac.api.Messages;
import com.sun.tools.javac.code.Type.AnnotatedType;
+import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.util.List;
@@ -127,7 +128,7 @@
}
/**
- * Get a localized string represenation for a given type.
+ * Get a localized string representation for a given type.
*
* @param t type to be displayed
* @param locale the locale in which the string is to be rendered
@@ -138,7 +139,7 @@
}
/**
- * Get a localized string represenation for a given symbol.
+ * Get a localized string representation for a given symbol.
*
* @param s symbol to be displayed
* @param locale the locale in which the string is to be rendered
@@ -182,7 +183,33 @@
@Override
public String visitArrayType(ArrayType t, Locale locale) {
- return visit(t.elemtype, locale) + "[]";
+ StringBuilder res = new StringBuilder();
+ printBaseElementType(t, res, locale);
+ printBrackets(t, res, locale);
+ return res.toString();
+ }
+
+ void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
+ Type arrel = t;
+ while (arrel.getKind() == TypeKind.ARRAY) {
+ arrel = arrel.unannotatedType();
+ arrel = ((ArrayType) arrel).elemtype;
+ }
+ sb.append(visit(arrel, locale));
+ }
+
+ void printBrackets(Type t, StringBuilder sb, Locale locale) {
+ Type arrel = t;
+ while (arrel.getKind() == TypeKind.ARRAY) {
+ if (arrel.isAnnotated()) {
+ sb.append(' ');
+ sb.append(arrel.getAnnotationMirrors());
+ sb.append(' ');
+ }
+ sb.append("[]");
+ arrel = arrel.unannotatedType();
+ arrel = ((ArrayType) arrel).elemtype;
+ }
}
@Override
@@ -237,10 +264,22 @@
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
if (t.typeAnnotations != null &&
t.typeAnnotations.nonEmpty()) {
- // TODO: better logic for arrays, ...
- return "(" + t.typeAnnotations + " :: " + visit(t.underlyingType, locale) + ")";
+ if (t.underlyingType.getKind() == TypeKind.ARRAY) {
+ StringBuilder res = new StringBuilder();
+ printBaseElementType(t, res, locale);
+ printBrackets(t, res, locale);
+ return res.toString();
+ } else if (t.underlyingType.getKind() == TypeKind.DECLARED &&
+ t.underlyingType.getEnclosingType() != Type.noType) {
+ return visit(t.underlyingType.getEnclosingType(), locale) +
+ ". " +
+ t.typeAnnotations +
+ " " + className((ClassType)t.underlyingType, false, locale);
+ } else {
+ return t.typeAnnotations + " " + visit(t.underlyingType, locale);
+ }
} else {
- return "({} :: " + visit(t.underlyingType, locale) + ")";
+ return visit(t.underlyingType, locale);
}
}
@@ -253,7 +292,7 @@
/**
* Converts a class name into a (possibly localized) string. Anonymous
- * inner classes gets converted into a localized string.
+ * inner classes get converted into a localized string.
*
* @param t the type of the class whose name is to be rendered
* @param longform if set, the class' fullname is displayed - if unset the
@@ -266,7 +305,7 @@
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
- s.append("&");
+ s.append('&');
s.append(visit(is.head, locale));
}
return s.toString();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Tue May 14 15:04:06 2013 -0700
@@ -25,8 +25,6 @@
package com.sun.tools.javac.code;
-import com.sun.tools.javac.model.JavacAnnoConstructs;
-import com.sun.tools.javac.model.JavacTypes;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.EnumMap;
@@ -34,10 +32,10 @@
import java.util.Map;
import java.util.Set;
-import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.*;
import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.model.JavacAnnoConstructs;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.code.Flags.*;
@@ -729,7 +727,7 @@
return s.toString();
} else if (sym.name.isEmpty()) {
String s;
- ClassType norm = (ClassType) tsym.type;
+ ClassType norm = (ClassType) tsym.type.unannotatedType();
if (norm == null) {
s = Log.getLocalizedString("anonymous.class", (Object)null);
} else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
@@ -781,7 +779,7 @@
return
getEnclosingType().isErroneous() ||
isErroneous(getTypeArguments()) ||
- this != tsym.type && tsym.type.isErroneous();
+ this != tsym.type.unannotatedType() && tsym.type.isErroneous();
}
public boolean isParameterized() {
@@ -1693,7 +1691,10 @@
@Override
public String toString() {
- // TODO more logic for arrays, etc.
+ // This method is only used for internal debugging output.
+ // See
+ // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
+ // for the user-visible logic.
if (typeAnnotations != null &&
!typeAnnotations.isEmpty()) {
return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
@@ -1705,9 +1706,13 @@
@Override
public boolean contains(Type t) { return underlyingType.contains(t); }
- // TODO: attach annotations?
@Override
- public Type withTypeVar(Type t) { return underlyingType.withTypeVar(t); }
+ public Type withTypeVar(Type t) {
+ // Don't create a new AnnotatedType, as 'this' will
+ // get its annotations set later.
+ underlyingType = underlyingType.withTypeVar(t);
+ return this;
+ }
// TODO: attach annotations?
@Override
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Tue May 14 15:04:06 2013 -0700
@@ -27,6 +27,7 @@
import java.util.Iterator;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.util.*;
/** A type annotation position.
@@ -145,9 +146,18 @@
// For class extends, implements, and throws clauses
public int type_index = Integer.MIN_VALUE;
- // For exception parameters, index into exception table
+ // For exception parameters, index into exception table.
+ // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
+ // to the catch type index - that value is only temporary.
+ // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
+ // we use that value to determine the exception table index.
public int exception_index = Integer.MIN_VALUE;
+ // If this type annotation is within a lambda expression,
+ // store a pointer to the lambda expression tree in order
+ // to allow a later translation to the right method.
+ public JCLambda onLambda = null;
+
public TypeAnnotationPosition() {}
@Override
@@ -258,6 +268,11 @@
sb.append(", pos = ");
sb.append(pos);
+ if (onLambda != null) {
+ sb.append(", onLambda hash = ");
+ sb.append(onLambda.hashCode());
+ }
+
sb.append(']');
return sb.toString();
}
@@ -271,6 +286,17 @@
return !type.isLocal() || isValidOffset;
}
+
+ public boolean matchesPos(int pos) {
+ return this.pos == pos;
+ }
+
+ public void updatePosOffset(int to) {
+ offset = to;
+ lvarOffset = new int[]{to};
+ isValidOffset = true;
+ }
+
/**
* Decode the binary representation for a type path and set
* the {@code location} field.
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Tue May 14 15:04:06 2013 -0700
@@ -49,12 +49,16 @@
import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.Annotator;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeScanner;
@@ -81,17 +85,18 @@
* determine the correct positions for type annotations.
* This version only visits types in signatures and should be
* called from MemberEnter.
- * The method returns the Annotator object that should be added
- * to the correct Annotate queue for later processing.
+ * The method takes the Annotate object as parameter and
+ * adds an Annotator to the correct Annotate queue for
+ * later processing.
*/
- public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
- final Log log, final JCClassDecl tree) {
- return new Annotator() {
+ public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
+ final Log log, final JCClassDecl tree, Annotate annotate) {
+ annotate.afterRepeated( new Annotator() {
@Override
public void enterAnnotation() {
new TypeAnnotationPositions(syms, names, log, true).scan(tree);
}
- };
+ } );
}
/**
@@ -102,9 +107,103 @@
new TypeAnnotationPositions(syms, names, log, false).scan(tree);
}
- private static class TypeAnnotationPositions extends TreeScanner {
+ public enum AnnotationType { DECLARATION, TYPE, BOTH };
- private enum AnnotationType { DECLARATION, TYPE, BOTH };
+ /**
+ * Determine whether an annotation is a declaration annotation,
+ * a type annotation, or both.
+ */
+ public static AnnotationType annotationType(Symtab syms, Names names,
+ Attribute.Compound a, Symbol s) {
+ Attribute.Compound atTarget =
+ a.type.tsym.attribute(syms.annotationTargetType.tsym);
+ if (atTarget == null) {
+ return inferTargetMetaInfo(a, s);
+ }
+ Attribute atValue = atTarget.member(names.value);
+ if (!(atValue instanceof Attribute.Array)) {
+ Assert.error("annotationType(): bad @Target argument " + atValue +
+ " (" + atValue.getClass() + ")");
+ return AnnotationType.DECLARATION; // error recovery
+ }
+ Attribute.Array arr = (Attribute.Array) atValue;
+ boolean isDecl = false, isType = false;
+ for (Attribute app : arr.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ Assert.error("annotationType(): unrecognized Attribute kind " + app +
+ " (" + app.getClass() + ")");
+ isDecl = true;
+ continue;
+ }
+ Attribute.Enum e = (Attribute.Enum) app;
+ if (e.value.name == names.TYPE) {
+ if (s.kind == Kinds.TYP)
+ isDecl = true;
+ } else if (e.value.name == names.FIELD) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind != Kinds.MTH)
+ isDecl = true;
+ } else if (e.value.name == names.METHOD) {
+ if (s.kind == Kinds.MTH &&
+ !s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.PARAMETER) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.CONSTRUCTOR) {
+ if (s.kind == Kinds.MTH &&
+ s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.LOCAL_VARIABLE) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) == 0)
+ isDecl = true;
+ } else if (e.value.name == names.ANNOTATION_TYPE) {
+ if (s.kind == Kinds.TYP &&
+ (s.flags() & Flags.ANNOTATION) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.PACKAGE) {
+ if (s.kind == Kinds.PCK)
+ isDecl = true;
+ } else if (e.value.name == names.TYPE_USE) {
+ if (s.kind == Kinds.TYP ||
+ s.kind == Kinds.VAR ||
+ (s.kind == Kinds.MTH && !s.isConstructor() &&
+ !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+ (s.kind == Kinds.MTH && s.isConstructor()))
+ isType = true;
+ } else if (e.value.name == names.TYPE_PARAMETER) {
+ /* Irrelevant in this case */
+ // TYPE_PARAMETER doesn't aid in distinguishing between
+ // Type annotations and declaration annotations on an
+ // Element
+ } else {
+ Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+ " (" + e.value.name.getClass() + ")");
+ isDecl = true;
+ }
+ }
+ if (isDecl && isType) {
+ return AnnotationType.BOTH;
+ } else if (isType) {
+ return AnnotationType.TYPE;
+ } else {
+ return AnnotationType.DECLARATION;
+ }
+ }
+
+ /** Infer the target annotation kind, if none is give.
+ * We only infer declaration annotations.
+ */
+ private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+ return AnnotationType.DECLARATION;
+ }
+
+
+ private static class TypeAnnotationPositions extends TreeScanner {
private final Symtab syms;
private final Names names;
@@ -154,7 +253,7 @@
ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
for (Attribute.Compound a : annotations) {
- switch (annotationType(a, sym)) {
+ switch (annotationType(syms, names, a, sym)) {
case DECLARATION:
declAnnos.append(a);
break;
@@ -175,6 +274,10 @@
sym.annotations.reset();
sym.annotations.setDeclarationAttributes(declAnnos.toList());
+ if (typeAnnos.isEmpty()) {
+ return;
+ }
+
List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
if (type == null) {
@@ -190,16 +293,33 @@
if (sym.getKind() == ElementKind.METHOD) {
sym.type.asMethodType().restype = type;
+ } else if (sym.getKind() == ElementKind.PARAMETER) {
+ sym.type = type;
+ if (sym.getQualifiedName().equals(names._this)) {
+ sym.owner.type.asMethodType().recvtype = type;
+ // note that the typeAnnotations will also be added to the owner below.
+ } else {
+ MethodType methType = sym.owner.type.asMethodType();
+ List<VarSymbol> params = ((MethodSymbol)sym.owner).params;
+ List<Type> oldArgs = methType.argtypes;
+ ListBuffer<Type> newArgs = new ListBuffer<Type>();
+ while (params.nonEmpty()) {
+ if (params.head == sym) {
+ newArgs.add(type);
+ } else {
+ newArgs.add(oldArgs.head);
+ }
+ oldArgs = oldArgs.tail;
+ params = params.tail;
+ }
+ methType.argtypes = newArgs.toList();
+ }
} else {
sym.type = type;
}
sym.annotations.appendUniqueTypes(typeAnnotations);
- if (sym.getKind() == ElementKind.PARAMETER &&
- sym.getQualifiedName().equals(names._this)) {
- sym.owner.type.asMethodType().recvtype = type;
- // note that the typeAnnotations will also be added to the owner below.
- }
+
if (sym.getKind() == ElementKind.PARAMETER ||
sym.getKind() == ElementKind.LOCAL_VARIABLE ||
sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
@@ -276,10 +396,21 @@
TypeAnnotationPosition p = a.position;
p.location = p.location.prependList(depth.toList());
}
+ typetree.type = toreturn;
return toreturn;
} else if (type.hasTag(TypeTag.TYPEVAR)) {
// Nothing to do for type variables.
return type;
+ } else if (type.getKind() == TypeKind.UNION) {
+ // There is a TypeKind, but no TypeTag.
+ JCTypeUnion tutree = (JCTypeUnion) typetree;
+ JCExpression fst = tutree.alternatives.get(0);
+ Type res = typeWithAnnotations(fst, fst.type, annotations, log);
+ fst.type = res;
+ // TODO: do we want to set res as first element in uct.alternatives?
+ // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
+ // Return the un-annotated union-type.
+ return type;
} else {
Type enclTy = type;
Element enclEl = type.asElement();
@@ -357,6 +488,7 @@
}
Type ret = typeWithAnnotations(type, enclTy, annotations);
+ typetree.type = ret;
return ret;
}
}
@@ -480,94 +612,6 @@
return new Attribute.TypeCompound(a, p);
}
- private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
- Attribute.Compound atTarget =
- a.type.tsym.attribute(syms.annotationTargetType.tsym);
- if (atTarget == null) {
- return inferTargetMetaInfo(a, s);
- }
- Attribute atValue = atTarget.member(names.value);
- if (!(atValue instanceof Attribute.Array)) {
- Assert.error("annotationType(): bad @Target argument " + atValue +
- " (" + atValue.getClass() + ")");
- return AnnotationType.DECLARATION; // error recovery
- }
- Attribute.Array arr = (Attribute.Array) atValue;
- boolean isDecl = false, isType = false;
- for (Attribute app : arr.values) {
- if (!(app instanceof Attribute.Enum)) {
- Assert.error("annotationType(): unrecognized Attribute kind " + app +
- " (" + app.getClass() + ")");
- isDecl = true;
- continue;
- }
- Attribute.Enum e = (Attribute.Enum) app;
- if (e.value.name == names.TYPE) {
- if (s.kind == Kinds.TYP)
- isDecl = true;
- } else if (e.value.name == names.FIELD) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind != Kinds.MTH)
- isDecl = true;
- } else if (e.value.name == names.METHOD) {
- if (s.kind == Kinds.MTH &&
- !s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.PARAMETER) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) != 0)
- isDecl = true;
- } else if (e.value.name == names.CONSTRUCTOR) {
- if (s.kind == Kinds.MTH &&
- s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.LOCAL_VARIABLE) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) == 0)
- isDecl = true;
- } else if (e.value.name == names.ANNOTATION_TYPE) {
- if (s.kind == Kinds.TYP &&
- (s.flags() & Flags.ANNOTATION) != 0)
- isDecl = true;
- } else if (e.value.name == names.PACKAGE) {
- if (s.kind == Kinds.PCK)
- isDecl = true;
- } else if (e.value.name == names.TYPE_USE) {
- if (s.kind == Kinds.TYP ||
- s.kind == Kinds.VAR ||
- (s.kind == Kinds.MTH && !s.isConstructor() &&
- !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
- (s.kind == Kinds.MTH && s.isConstructor()))
- isType = true;
- } else if (e.value.name == names.TYPE_PARAMETER) {
- /* Irrelevant in this case */
- // TYPE_PARAMETER doesn't aid in distinguishing between
- // Type annotations and declaration annotations on an
- // Element
- } else {
- Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
- " (" + e.value.name.getClass() + ")");
- isDecl = true;
- }
- }
- if (isDecl && isType) {
- return AnnotationType.BOTH;
- } else if (isType) {
- return AnnotationType.TYPE;
- } else {
- return AnnotationType.DECLARATION;
- }
- }
-
- /** Infer the target annotation kind, if none is give.
- * We only infer declaration annotations.
- */
- private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
- return AnnotationType.DECLARATION;
- }
-
/* This is the beginning of the second part of organizing
* type annotations: determine the type annotation positions.
@@ -585,7 +629,13 @@
switch (frame.getKind()) {
case TYPE_CAST:
+ JCTypeCast frameTC = (JCTypeCast) frame;
p.type = TargetType.CAST;
+ if (frameTC.clazz.hasTag(Tag.TYPEINTERSECTION)) {
+ // This case was already handled by INTERSECTION_TYPE
+ } else {
+ p.type_index = 0;
+ }
p.pos = frame.pos;
return;
@@ -595,8 +645,22 @@
return;
case NEW_CLASS:
- JCNewClass frameNewClass = (JCNewClass)frame;
- if (frameNewClass.typeargs.contains(tree)) {
+ JCNewClass frameNewClass = (JCNewClass) frame;
+ if (frameNewClass.def != null) {
+ // Special handling for anonymous class instantiations
+ JCClassDecl frameClassDecl = frameNewClass.def;
+ if (frameClassDecl.extending == tree) {
+ p.type = TargetType.CLASS_EXTENDS;
+ p.type_index = -1;
+ } else if (frameClassDecl.implementing.contains(tree)) {
+ p.type = TargetType.CLASS_EXTENDS;
+ p.type_index = frameClassDecl.implementing.indexOf(tree);
+ } else {
+ // In contrast to CLASS below, typarams cannot occur here.
+ Assert.error("Could not determine position of tree " + tree +
+ " within frame " + frame);
+ }
+ } else if (frameNewClass.typeargs.contains(tree)) {
p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
p.type_index = frameNewClass.typeargs.indexOf(tree);
} else {
@@ -649,6 +713,8 @@
}
case PARAMETERIZED_TYPE: {
+ List<JCTree> newPath = path.tail;
+
if (((JCTypeApply)frame).clazz == tree) {
// generic: RAW; noop
} else if (((JCTypeApply)frame).arguments.contains(tree)) {
@@ -656,13 +722,21 @@
int arg = taframe.arguments.indexOf(tree);
p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
- locateNestedTypes(taframe.type, p);
+ Type typeToUse;
+ if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
+ // If we are within an anonymous class instantiation, use its type,
+ // because it contains a correctly nested type.
+ typeToUse = newPath.tail.head.type;
+ } else {
+ typeToUse = taframe.type;
+ }
+
+ locateNestedTypes(typeToUse, p);
} else {
Assert.error("Could not determine type argument position of tree " + tree +
" within frame " + frame);
}
- List<JCTree> newPath = path.tail;
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
}
@@ -780,6 +854,9 @@
default:
Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
}
+ if (v.getKind() != ElementKind.FIELD) {
+ v.owner.annotations.appendUniqueTypes(v.getRawTypeAttributes());
+ }
return;
case ANNOTATED_TYPE: {
@@ -789,6 +866,11 @@
// not care about inner types.
JCAnnotatedType atypetree = (JCAnnotatedType) frame;
final Type utype = atypetree.underlyingType.type;
+ if (utype == null) {
+ // This might happen during DeferredAttr;
+ // we will be back later.
+ return;
+ }
Symbol tsym = utype.tsym;
if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
utype.getKind().equals(TypeKind.WILDCARD) ||
@@ -806,8 +888,6 @@
}
case UNION_TYPE: {
- // TODO: can we store any information here to help in
- // determining the final position?
List<JCTree> newPath = path.tail;
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
@@ -873,11 +953,20 @@
private static int methodParamIndex(List<JCTree> path, JCTree param) {
List<JCTree> curr = path;
- while (curr.head.getTag() != Tag.METHODDEF) {
+ while (curr.head.getTag() != Tag.METHODDEF &&
+ curr.head.getTag() != Tag.LAMBDA) {
curr = curr.tail;
}
- JCMethodDecl method = (JCMethodDecl)curr.head;
- return method.params.indexOf(param);
+ if (curr.head.getTag() == Tag.METHODDEF) {
+ JCMethodDecl method = (JCMethodDecl)curr.head;
+ return method.params.indexOf(param);
+ } else if (curr.head.getTag() == Tag.LAMBDA) {
+ JCLambda lambda = (JCLambda)curr.head;
+ return lambda.params.indexOf(param);
+ } else {
+ Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
+ return -1;
+ }
}
// Each class (including enclosed inner classes) is visited separately.
@@ -889,6 +978,7 @@
if (isInClass)
return;
isInClass = true;
+
if (sigOnly) {
scan(tree.mods);
scan(tree.typarams);
@@ -910,7 +1000,9 @@
return;
}
if (sigOnly) {
- {
+ if (!tree.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.METHOD_RETURN;
if (tree.sym.isConstructor()) {
@@ -923,7 +1015,10 @@
tree.sym, pos);
}
}
- if (tree.recvparam != null && tree.recvparam.sym != null) {
+ if (tree.recvparam != null && tree.recvparam.sym != null &&
+ !tree.recvparam.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
// TODO: make sure there are no declaration annotations.
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.METHOD_RECEIVER;
@@ -933,11 +1028,15 @@
}
int i = 0;
for (JCVariableDecl param : tree.params) {
- TypeAnnotationPosition pos = new TypeAnnotationPosition();
- pos.type = TargetType.METHOD_FORMAL_PARAMETER;
- pos.parameter_index = i;
- pos.pos = param.vartype.pos;
- separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+ pos.parameter_index = i;
+ pos.pos = param.vartype.pos;
+ separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ }
++i;
}
}
@@ -958,16 +1057,53 @@
pop();
}
+ /* Store a reference to the current lambda expression, to
+ * be used by all type annotations within this expression.
+ */
+ private JCLambda currentLambda = null;
+
+ public void visitLambda(JCLambda tree) {
+ JCLambda prevLambda = currentLambda;
+ try {
+ currentLambda = tree;
+
+ int i = 0;
+ for (JCVariableDecl param : tree.params) {
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+ pos.parameter_index = i;
+ pos.pos = param.vartype.pos;
+ pos.onLambda = tree;
+ separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ }
+ ++i;
+ }
+
+ push(tree);
+ scan(tree.body);
+ scan(tree.params);
+ pop();
+ } finally {
+ currentLambda = prevLambda;
+ }
+ }
+
/**
* Resolve declaration vs. type annotations in variable declarations and
* then determine the positions.
*/
@Override
public void visitVarDef(final JCVariableDecl tree) {
- if (tree.sym == null) {
+ if (tree.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ } else if (tree.sym == null) {
// Something is wrong already. Quietly ignore.
} else if (tree.sym.getKind() == ElementKind.PARAMETER) {
- // Parameters are handled in visitMethodDef above.
+ // Parameters are handled in visitMethodDef or visitLambda.
} else if (tree.sym.getKind() == ElementKind.FIELD) {
if (sigOnly) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
@@ -979,16 +1115,19 @@
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.LOCAL_VARIABLE;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.EXCEPTION_PARAMETER;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.RESOURCE_VARIABLE;
pos.pos = tree.pos;
+ pos.onLambda = currentLambda;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
// No type annotations can occur here.
@@ -1031,6 +1170,40 @@
}
@Override
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.def != null &&
+ !tree.def.mods.annotations.isEmpty()) {
+ JCClassDecl classdecl = tree.def;
+ TypeAnnotationPosition pos = new TypeAnnotationPosition();
+ pos.type = TargetType.CLASS_EXTENDS;
+ pos.pos = tree.pos;
+ if (classdecl.extending == tree.clazz) {
+ pos.type_index = -1;
+ } else if (classdecl.implementing.contains(tree.clazz)) {
+ pos.type_index = classdecl.implementing.indexOf(tree.clazz);
+ } else {
+ // In contrast to CLASS elsewhere, typarams cannot occur here.
+ Assert.error("Could not determine position of tree " + tree);
+ }
+ Type before = classdecl.sym.type;
+ separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
+
+ // classdecl.sym.type now contains an annotated type, which
+ // is not what we want there.
+ // TODO: should we put this type somewhere in the superclass/interface?
+ classdecl.sym.type = before;
+ }
+
+ scan(tree.encl);
+ scan(tree.typeargs);
+ scan(tree.clazz);
+ scan(tree.args);
+
+ // The class body will already be scanned.
+ // scan(tree.def);
+ }
+
+ @Override
public void visitNewArray(JCNewArray tree) {
findPosition(tree, tree, tree.annotations);
int dimAnnosCount = tree.dimAnnotations.size();
@@ -1040,6 +1213,7 @@
for (int i = 0; i < dimAnnosCount; ++i) {
TypeAnnotationPosition p = new TypeAnnotationPosition();
p.pos = tree.pos;
+ p.onLambda = currentLambda;
p.type = TargetType.NEW;
if (i != 0) {
depth = depth.append(TypePathEntry.ARRAY);
@@ -1053,18 +1227,23 @@
// int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
// TODO: is depth.size == i here?
JCExpression elemType = tree.elemtype;
+ depth = depth.append(TypePathEntry.ARRAY);
while (elemType != null) {
if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
JCAnnotatedType at = (JCAnnotatedType)elemType;
TypeAnnotationPosition p = new TypeAnnotationPosition();
p.type = TargetType.NEW;
p.pos = tree.pos;
- p.location = p.location.appendList(depth.toList());
+ p.onLambda = currentLambda;
+ locateNestedTypes(elemType.type, p);
+ p.location = p.location.prependList(depth.toList());
setTypeAnnotationPos(at.annotations, p);
elemType = at.underlyingType;
} else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
depth = depth.append(TypePathEntry.ARRAY);
elemType = ((JCArrayTypeTree)elemType).elemtype;
+ } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
+ elemType = ((JCFieldAccess)elemType).selected;
} else {
break;
}
@@ -1076,10 +1255,11 @@
if (!annotations.isEmpty()) {
/*
System.out.println("Finding pos for: " + annotations);
- System.out.println(" tree: " + tree);
- System.out.println(" frame: " + frame);
+ System.out.println(" tree: " + tree + " kind: " + tree.getKind());
+ System.out.println(" frame: " + frame + " kind: " + frame.getKind());
*/
TypeAnnotationPosition p = new TypeAnnotationPosition();
+ p.onLambda = currentLambda;
resolveFrame(tree, frame, frames.toList(), p);
setTypeAnnotationPos(annotations, p);
}
@@ -1088,8 +1268,17 @@
private static void setTypeAnnotationPos(List<JCAnnotation> annotations,
TypeAnnotationPosition position) {
for (JCAnnotation anno : annotations) {
- ((Attribute.TypeCompound) anno.attribute).position = position;
+ // attribute might be null during DeferredAttr;
+ // we will be back later.
+ if (anno.attribute != null) {
+ ((Attribute.TypeCompound) anno.attribute).position = position;
+ }
}
}
+
+ @Override
+ public String toString() {
+ return super.toString() + ": sigOnly: " + sigOnly;
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue May 14 15:04:06 2013 -0700
@@ -26,7 +26,6 @@
package com.sun.tools.javac.code;
import java.lang.ref.SoftReference;
-import java.util.Comparator;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Locale;
@@ -34,8 +33,6 @@
import java.util.Set;
import java.util.WeakHashMap;
-import javax.lang.model.type.TypeKind;
-
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
@@ -204,7 +201,7 @@
WildcardType unb = new WildcardType(syms.objectType,
BoundKind.UNBOUND,
syms.boundClass,
- (TypeVar)parms.head);
+ (TypeVar)parms.head.unannotatedType());
if (!containsType(args.head, unb))
return false;
parms = parms.tail;
@@ -268,7 +265,7 @@
List<Type> opens = openVars.toList();
ListBuffer<Type> qs = new ListBuffer<Type>();
for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
- qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
+ qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
}
res = subst(res, opens, qs.toList());
}
@@ -581,12 +578,12 @@
//simply replace the wildcards with its bound
for (Type t : formalInterface.getTypeArguments()) {
if (actualTypeargs.head.hasTag(WILDCARD)) {
- WildcardType wt = (WildcardType)actualTypeargs.head;
+ WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType();
Type bound;
switch (wt.kind) {
case EXTENDS:
case UNBOUND:
- CapturedType capVar = (CapturedType)capturedTypeargs.head;
+ CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType();
//use declared bound if it doesn't depend on formal type-args
bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
wt.type : capVar.bound;
@@ -964,6 +961,9 @@
isSameTypeStrict.visit(t, s) :
isSameTypeLoose.visit(t, s);
}
+ public boolean isSameAnnotatedType(Type t, Type s) {
+ return isSameAnnotatedType.visit(t, s);
+ }
// where
abstract class SameTypeVisitor extends TypeRelation {
@@ -982,7 +982,7 @@
if (s.tag == TYPEVAR) {
//type-substitution does not preserve type-var types
//check that type var symbols and bounds are indeed the same
- return sameTypeVars((TypeVar)t, (TypeVar)s);
+ return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
}
else {
//special case for s == ? super X, where upper(s) = u
@@ -1096,7 +1096,9 @@
* Standard type-equality relation - type variables are considered
* equals if they share the same type symbol.
*/
- TypeRelation isSameTypeLoose = new SameTypeVisitor() {
+ TypeRelation isSameTypeLoose = new LooseSameTypeVisitor();
+
+ private class LooseSameTypeVisitor extends SameTypeVisitor {
@Override
boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
@@ -1126,12 +1128,29 @@
if (!s.hasTag(WILDCARD)) {
return false;
} else {
- WildcardType t2 = (WildcardType)s;
+ WildcardType t2 = (WildcardType)s.unannotatedType();
return t.kind == t2.kind &&
isSameType(t.type, t2.type, true);
}
}
};
+
+ /**
+ * A version of LooseSameTypeVisitor that takes AnnotatedTypes
+ * into account.
+ */
+ TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
+ @Override
+ public Boolean visitAnnotatedType(AnnotatedType t, Type s) {
+ if (!s.isAnnotated())
+ return false;
+ if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors()))
+ return false;
+ if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors()))
+ return false;
+ return visit(t.underlyingType, s);
+ }
+ };
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Contains Type">
@@ -1140,7 +1159,7 @@
case UNDETVAR:
if (s.tag == WILDCARD) {
UndetVar undetvar = (UndetVar)t;
- WildcardType wt = (WildcardType)s;
+ WildcardType wt = (WildcardType)s.unannotatedType();
switch(wt.kind) {
case UNBOUND: //similar to ? extends Object
case EXTENDS: {
@@ -1207,7 +1226,7 @@
private Type U(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
if (w.isSuperBound())
return w.bound == null ? syms.objectType : w.bound.bound;
else
@@ -1218,7 +1237,7 @@
private Type L(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
if (w.isExtendsBound())
return syms.botType;
else
@@ -1276,15 +1295,15 @@
};
public boolean isCaptureOf(Type s, WildcardType t) {
- if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
+ if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured())
return false;
- return isSameWildcard(t, ((CapturedType)s).wildcard);
+ return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
}
public boolean isSameWildcard(WildcardType t, Type s) {
if (s.tag != WILDCARD)
return false;
- WildcardType w = (WildcardType)s;
+ WildcardType w = (WildcardType)s.unannotatedType();
return w.kind == t.kind && w.type == t.type;
}
@@ -1373,8 +1392,8 @@
if (t.isCompound() || s.isCompound()) {
return !t.isCompound() ?
- visitIntersectionType((IntersectionClassType)s, t, true) :
- visitIntersectionType((IntersectionClassType)t, s, false);
+ visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
+ visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
}
if (s.tag == CLASS || s.tag == ARRAY) {
@@ -3070,7 +3089,7 @@
for (Type t : tvars) {
if (!first) s.append(", ");
first = false;
- appendTyparamString(((TypeVar)t), s);
+ appendTyparamString(((TypeVar)t.unannotatedType()), s);
}
s.append('>');
return s.toString();
@@ -3710,9 +3729,9 @@
!currentS.isEmpty()) {
if (currentS.head != currentT.head) {
captured = true;
- WildcardType Ti = (WildcardType)currentT.head;
+ WildcardType Ti = (WildcardType)currentT.head.unannotatedType();
Type Ui = currentA.head.getUpperBound();
- CapturedType Si = (CapturedType)currentS.head;
+ CapturedType Si = (CapturedType)currentS.head.unannotatedType();
if (Ui == null)
Ui = syms.objectType;
switch (Ti.kind) {
@@ -3749,6 +3768,7 @@
ListBuffer<Type> result = lb();
for (Type t : types) {
if (t.tag == WILDCARD) {
+ t = t.unannotatedType();
Type bound = ((WildcardType)t).getExtendsBound();
if (bound == null)
bound = syms.objectType;
@@ -3842,7 +3862,7 @@
private boolean giveWarning(Type from, Type to) {
List<Type> bounds = to.isCompound() ?
- ((IntersectionClassType)to).getComponents() : List.of(to);
+ ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to);
for (Type b : bounds) {
Type subFrom = asSub(from, b.tsym);
if (b.isParameterized() &&
@@ -4107,7 +4127,7 @@
Type B(Type t) {
while (t.tag == WILDCARD) {
- WildcardType w = (WildcardType)t;
+ WildcardType w = (WildcardType)t.unannotatedType();
t = high ?
w.getExtendsBound() :
w.getSuperBound();
@@ -4182,7 +4202,7 @@
public boolean equals(Object obj) {
return (obj instanceof UniqueType) &&
- types.isSameType(type, ((UniqueType)obj).type);
+ types.isSameAnnotatedType(type, ((UniqueType)obj).type);
}
public String toString() {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue May 14 15:04:06 2013 -0700
@@ -216,18 +216,42 @@
Attribute.Compound enterAnnotation(JCAnnotation a,
Type expected,
Env<AttrContext> env) {
+ return enterAnnotation(a, expected, env, false);
+ }
+
+ Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
+ Type expected,
+ Env<AttrContext> env) {
+ return (Attribute.TypeCompound) enterAnnotation(a, expected, env, true);
+ }
+
+ // boolean typeAnnotation determines whether the method returns
+ // a Compound (false) or TypeCompound (true).
+ Attribute.Compound enterAnnotation(JCAnnotation a,
+ Type expected,
+ Env<AttrContext> env,
+ boolean typeAnnotation) {
// The annotation might have had its type attributed (but not checked)
// by attr.attribAnnotationTypes during MemberEnter, in which case we do not
// need to do it again.
Type at = (a.annotationType.type != null ? a.annotationType.type
: attr.attribType(a.annotationType, env));
a.type = chk.checkType(a.annotationType.pos(), at, expected);
- if (a.type.isErroneous())
- return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+ if (a.type.isErroneous()) {
+ if (typeAnnotation) {
+ return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(), null);
+ } else {
+ return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+ }
+ }
if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
log.error(a.annotationType.pos(),
"not.annotation.type", a.type.toString());
- return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+ if (typeAnnotation) {
+ return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(), null);
+ } else {
+ return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
+ }
}
List<JCExpression> args = a.args;
if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
@@ -266,12 +290,21 @@
((MethodSymbol)method, value));
t.type = result;
}
- // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
- // However, how do we find the correct position?
- Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
- // TODO: is this something we want? Who would use it?
- // a.attribute = ac;
- return ac;
+ if (typeAnnotation) {
+ if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
+ // Create a new TypeCompound
+ Attribute.TypeCompound tc = new Attribute.TypeCompound(a.type, buf.toList(), new TypeAnnotationPosition());
+ a.attribute = tc;
+ return tc;
+ } else {
+ // Use an existing TypeCompound
+ return a.attribute;
+ }
+ } else {
+ Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
+ a.attribute = ac;
+ return ac;
+ }
}
Attribute enterAttributeValue(Type expected,
@@ -354,15 +387,6 @@
return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
- Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
- Type expected,
- Env<AttrContext> env) {
- Attribute.Compound c = enterAnnotation(a, expected, env);
- Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
- a.attribute = tc;
- return tc;
- }
-
/* *********************************
* Support for repeating annotations
***********************************/
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue May 14 15:04:06 2013 -0700
@@ -768,7 +768,12 @@
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
try {
- memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
+ // Use null as symbol to not attach the type annotation to any symbol.
+ // The initializer will later also be visited and then we'll attach
+ // to the symbol.
+ // This prevents having multiple type annotations, just because of
+ // lazy constant value evaluation.
+ memberEnter.typeAnnotate(initializer, env, null);
annotate.flush();
Type itype = attribExpr(initializer, env, type);
if (itype.constValue() != null)
@@ -935,11 +940,6 @@
Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
attribType(tree.recvparam, newEnv);
chk.validate(tree.recvparam, newEnv);
- if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
- // The == covers the common non-generic case, but for generic classes we need isSameType;
- // note that equals didn't work.
- log.error(tree.recvparam.pos(), "incorrect.receiver.type");
- }
}
// annotation method checks
@@ -1112,6 +1112,18 @@
memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
annotate.flush();
+ {
+ // Store init and clinit type annotations with the ClassSymbol
+ // to allow output in Gen.normalizeDefs.
+ ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
+ List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
+ if ((tree.flags & STATIC) != 0) {
+ cs.annotations.appendClassInitTypeAttributes(tas);
+ } else {
+ cs.annotations.appendInitTypeAttributes(tas);
+ }
+ }
+
attribStats(tree.stats, localEnv);
} else {
// Create a new local environment with a local scope.
@@ -2131,6 +2143,11 @@
tree.constructor,
localEnv,
new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+ } else {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+ tree.clazz.type.tsym);
+ }
}
if (tree.constructor != null && tree.constructor.kind == MTH)
@@ -2195,6 +2212,20 @@
}
}
+ private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
+ Symbol sym) {
+ // Ensure that no declaration annotations are present.
+ // Note that a tree type might be an AnnotatedType with
+ // empty annotations, if only declaration annotations were given.
+ // This method will raise an error for such a type.
+ for (JCAnnotation ai : annotations) {
+ if (TypeAnnotations.annotationType(syms, names, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+ log.error(ai.pos(), "annotation.type.not.applicable");
+ }
+ }
+ }
+
+
/** Make an attributed null check tree.
*/
public JCExpression makeNullCheck(JCExpression arg) {
@@ -2221,6 +2252,10 @@
attribExpr(l.head, localEnv, syms.intType);
owntype = new ArrayType(owntype, syms.arrayClass);
}
+ if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+ tree.elemtype.type.tsym);
+ }
} else {
// we are seeing an untyped aggregate { ... }
// this is allowed only if the prototype is an array
@@ -3763,6 +3798,12 @@
}
}
owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
+ if (clazztype.isAnnotated()) {
+ // Use the same AnnotatedType, because it will have
+ // its annotations set later.
+ ((AnnotatedType)clazztype).underlyingType = owntype;
+ owntype = clazztype;
+ }
} else {
if (formals.length() != 0) {
log.error(tree.pos(), "wrong.number.type.args",
@@ -3961,7 +4002,14 @@
ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
for (JCAnnotation anno : annotations) {
- buf.append((Attribute.TypeCompound) anno.attribute);
+ if (anno.attribute != null) {
+ // TODO: this null-check is only needed for an obscure
+ // ordering issue, where annotate.flush is called when
+ // the attribute is not set yet. For an example failure
+ // try the referenceinfos/NestedTypes.java test.
+ // Any better solutions?
+ buf.append((Attribute.TypeCompound) anno.attribute);
+ }
}
return buf.toList();
}
@@ -4266,15 +4314,12 @@
tree.accept(typeAnnotationsValidator);
}
//where
- private final JCTree.Visitor typeAnnotationsValidator =
- new TreeScanner() {
+ private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() {
+
+ private boolean checkAllAnnotations = false;
+
public void visitAnnotation(JCAnnotation tree) {
- if (tree.hasTag(TYPE_ANNOTATION)) {
- // TODO: It seems to WMD as if the annotation in
- // parameters, in particular also the recvparam, are never
- // of type JCTypeAnnotation and therefore never checked!
- // Luckily this check doesn't really do anything that isn't
- // also done elsewhere.
+ if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) {
chk.validateTypeAnnotation(tree, false);
}
super.visitAnnotation(tree);
@@ -4288,15 +4333,10 @@
// super.visitTypeParameter(tree);
}
public void visitMethodDef(JCMethodDecl tree) {
- // Static methods cannot have receiver type annotations.
- // In test case FailOver15.java, the nested method getString has
- // a null sym, because an unknown class is instantiated.
- // I would say it's safe to skip.
- if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
- if (tree.recvparam != null) {
- // TODO: better error message. Is the pos good?
- log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
- }
+ if (tree.recvparam != null &&
+ tree.recvparam.vartype.type.getKind() != TypeKind.ERROR) {
+ checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
+ tree.recvparam.vartype.type.tsym);
}
if (tree.restype != null && tree.restype.type != null) {
validateAnnotatedType(tree.restype, tree.restype.type);
@@ -4318,9 +4358,30 @@
validateAnnotatedType(tree.clazz, tree.clazz.type);
super.visitTypeTest(tree);
}
- // TODO: what else do we need?
- // public void visitNewClass(JCNewClass tree) {
- // public void visitNewArray(JCNewArray tree) {
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ boolean prevCheck = this.checkAllAnnotations;
+ try {
+ this.checkAllAnnotations = true;
+ scan(((JCAnnotatedType)tree.clazz).annotations);
+ } finally {
+ this.checkAllAnnotations = prevCheck;
+ }
+ }
+ super.visitNewClass(tree);
+ }
+ public void visitNewArray(JCNewArray tree) {
+ if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ boolean prevCheck = this.checkAllAnnotations;
+ try {
+ this.checkAllAnnotations = true;
+ scan(((JCAnnotatedType)tree.elemtype).annotations);
+ } finally {
+ this.checkAllAnnotations = prevCheck;
+ }
+ }
+ super.visitNewArray(tree);
+ }
/* I would want to model this after
* com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue May 14 15:04:06 2013 -0700
@@ -1213,7 +1213,7 @@
/** Validate a type expression. That is,
* check that all type arguments of a parametric type are within
- * their bounds. This must be done in a second phase after type attributon
+ * their bounds. This must be done in a second phase after type attribution
* since a class might have a subclass as type parameter bound. E.g:
*
* <pre>{@code
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue May 14 15:04:06 2013 -0700
@@ -25,12 +25,12 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol;
@@ -46,7 +46,6 @@
import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
@@ -238,6 +237,24 @@
MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
MethodType lambdaType = (MethodType) sym.type;
+ {
+ MethodSymbol owner = (MethodSymbol) localContext.owner;
+ ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
+ ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
+
+ for (Attribute.TypeCompound tc : owner.getRawTypeAttributes()) {
+ if (tc.position.onLambda == tree) {
+ lambdaTypeAnnos.append(tc);
+ } else {
+ ownerTypeAnnos.append(tc);
+ }
+ }
+ if (lambdaTypeAnnos.nonEmpty()) {
+ owner.annotations.setTypeAttributes(ownerTypeAnnos.toList());
+ sym.annotations.setTypeAttributes(lambdaTypeAnnos.toList());
+ }
+ }
+
//create the method declaration hoisting the lambda body
JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field),
sym.name,
@@ -373,12 +390,15 @@
if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(translatedSym.type);
+ translatedSym.annotations.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
@@ -1676,24 +1696,33 @@
* synthetic lambda body
*/
Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) {
+ Symbol ret;
switch (skind) {
case CAPTURED_THIS:
- return sym; // self represented
+ ret = sym; // self represented
+ break;
case TYPE_VAR:
// Just erase the type var
- return new VarSymbol(sym.flags(), name,
+ ret = new VarSymbol(sym.flags(), name,
types.erasure(sym.type), sym.owner);
+ break;
case CAPTURED_VAR:
- return new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
+ ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
@Override
public Symbol baseSymbol() {
//keep mapping with original captured symbol
return sym;
}
};
+ break;
default:
- return makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
+ ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
}
+ if (ret != sym) {
+ ret.annotations.setDeclarationAttributes(sym.getRawAttributes());
+ ret.annotations.setTypeAttributes(sym.getRawTypeAttributes());
+ }
+ return ret;
}
void addSymbol(Symbol sym, LambdaSymbolKind skind) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue May 14 15:04:06 2013 -0700
@@ -28,6 +28,7 @@
import java.util.*;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.AnnotatedType;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.Option.PkgInfo;
import com.sun.tools.javac.tree.*;
@@ -2767,10 +2768,28 @@
}
public void visitAnnotatedType(JCAnnotatedType tree) {
- // No need to retain type annotations any longer.
+ // No need to retain type annotations in the tree
// tree.annotations = translate(tree.annotations);
+ tree.annotations = List.nil();
tree.underlyingType = translate(tree.underlyingType);
- result = tree.underlyingType;
+ // but maintain type annotations in the type.
+ if (tree.type.isAnnotated()) {
+ if (tree.underlyingType.type.isAnnotated()) {
+ // The erasure of a type variable might be annotated.
+ // Merge all annotations.
+ AnnotatedType newat = (AnnotatedType) tree.underlyingType.type;
+ AnnotatedType at = (AnnotatedType) tree.type;
+ at.underlyingType = newat.underlyingType;
+ newat.typeAnnotations = at.typeAnnotations.appendList(newat.typeAnnotations);
+ tree.type = newat;
+ } else {
+ // Create a new AnnotatedType to have the correct tag.
+ AnnotatedType oldat = (AnnotatedType) tree.type;
+ tree.type = new AnnotatedType(tree.underlyingType.type);
+ ((AnnotatedType) tree.type).typeAnnotations = oldat.typeAnnotations;
+ }
+ }
+ result = tree;
}
public void visitTypeCast(JCTypeCast tree) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue May 14 15:04:06 2013 -0700
@@ -31,7 +31,6 @@
import java.util.Map;
import java.util.Set;
-import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*;
@@ -617,7 +616,26 @@
if (TreeInfo.isEnumInit(tree)) {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else {
+ // Make sure type annotations are processed.
+ // But we don't have a symbol to attach them to yet - use null.
+ typeAnnotate(tree.vartype, env, null);
attr.attribType(tree.vartype, localEnv);
+ if (tree.nameexpr != null) {
+ attr.attribExpr(tree.nameexpr, localEnv);
+ MethodSymbol m = localEnv.enclMethod.sym;
+ if (m.isConstructor()) {
+ Type outertype = m.owner.owner.type;
+ if (outertype.hasTag(TypeTag.CLASS)) {
+ checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
+ checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
+ } else {
+ log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
+ }
+ } else {
+ checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
+ checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
+ }
+ }
}
} finally {
chk.setDeferredLintHandler(prevLintHandler);
@@ -651,10 +669,16 @@
enclScope.enter(v);
}
annotateLater(tree.mods.annotations, localEnv, v);
- typeAnnotate(tree.vartype, env, tree.sym);
+ typeAnnotate(tree.vartype, env, v);
annotate.flush();
v.pos = tree.pos;
}
+ // where
+ void checkType(JCTree tree, Type type, String diag) {
+ if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) {
+ log.error(tree, diag, type, tree.type);
+ }
+ }
/** Create a fresh environment for a variable's initializer.
* If the variable is a field, the owner of the environment's scope
@@ -1040,9 +1064,12 @@
isFirst = true;
}
}
- annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
+ TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
}
+ /*
+ * If the symbol is non-null, attach the type annotation to it.
+ */
private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
final Env<AttrContext> env,
final Symbol s) {
@@ -1075,8 +1102,10 @@
}
}
- s.annotations.appendTypeAttributesWithCompletion(
- annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
+ if (s != null) {
+ s.annotations.appendTypeAttributesWithCompletion(
+ annotate.new AnnotateRepeatedContext<Attribute.TypeCompound>(env, annotated, pos, log, true));
+ }
}
public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
@@ -1150,6 +1179,33 @@
// Do not annotate the body, just the signature.
// scan(tree.body);
}
+
+ @Override
+ public void visitVarDef(final JCVariableDecl tree) {
+ if (sym != null && sym.kind == Kinds.VAR) {
+ // Don't visit a parameter once when the sym is the method
+ // and once when the sym is the parameter.
+ scan(tree.mods);
+ scan(tree.vartype);
+ }
+ scan(tree.init);
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ // We can only hit a classdef if it is declared within
+ // a method. Ignore it - the class will be visited
+ // separately later.
+ }
+
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.def == null) {
+ // For an anonymous class instantiation the class
+ // will be visited separately.
+ super.visitNewClass(tree);
+ }
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue May 14 15:04:06 2013 -0700
@@ -1518,7 +1518,7 @@
break;
// exception parameter
case EXCEPTION_PARAMETER:
- position.exception_index = nextByte();
+ position.exception_index = nextChar();
break;
// method receiver
case METHOD_RECEIVER:
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue May 14 15:04:06 2013 -0700
@@ -632,7 +632,7 @@
acount++;
}
acount += writeJavaAnnotations(sym.getRawAttributes());
- acount += writeTypeAnnotations(sym.getRawTypeAttributes());
+ acount += writeTypeAnnotations(sym.getRawTypeAttributes(), false);
return acount;
}
@@ -759,44 +759,30 @@
return attrCount;
}
- int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) {
+ int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos, boolean inCode) {
if (typeAnnos.isEmpty()) return 0;
ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
for (Attribute.TypeCompound tc : typeAnnos) {
- if (tc.position == null || tc.position.type == TargetType.UNKNOWN) {
- boolean found = false;
- // TODO: the position for the container annotation of a
- // repeating type annotation has to be set.
- // This cannot be done when the container is created, because
- // then the position is not determined yet.
- // How can we link these pieces better together?
- if (tc.values.size() == 1) {
- Pair<MethodSymbol, Attribute> val = tc.values.get(0);
- if (val.fst.getSimpleName().contentEquals("value") &&
- val.snd instanceof Attribute.Array) {
- Attribute.Array arr = (Attribute.Array) val.snd;
- if (arr.values.length != 0 &&
- arr.values[0] instanceof Attribute.TypeCompound) {
- TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
- if (atycomp.position.type != TargetType.UNKNOWN) {
- tc.position = atycomp.position;
- found = true;
- }
- }
- }
- }
- if (!found) {
+ if (tc.hasUnknownPosition()) {
+ boolean fixed = tc.tryFixPosition();
+
+ // Could we fix it?
+ if (!fixed) {
// This happens for nested types like @A Outer. @B Inner.
// For method parameters we get the annotation twice! Once with
// a valid position, once unknown.
// TODO: find a cleaner solution.
- // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
+ PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+ pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
continue;
}
}
+
+ if (tc.position.type.isLocal() != inCode)
+ continue;
if (!tc.position.emitToClassfile())
continue;
switch (types.getRetention(tc)) {
@@ -936,7 +922,7 @@
break;
// exception parameter
case EXCEPTION_PARAMETER:
- databuf.appendByte(p.exception_index);
+ databuf.appendChar(p.exception_index);
break;
// method receiver
case METHOD_RECEIVER:
@@ -1241,6 +1227,9 @@
endAttr(alenIdx);
acount++;
}
+
+ acount += writeTypeAnnotations(code.meth.getRawTypeAttributes(), true);
+
endAttrs(acountIdx, acount);
}
//where
@@ -1627,7 +1616,7 @@
out = null;
} finally {
if (out != null) {
- // if we are propogating an exception, delete the file
+ // if we are propagating an exception, delete the file
out.close();
outFile.delete();
outFile = null;
@@ -1741,7 +1730,7 @@
acount += writeFlagAttrs(c.flags());
acount += writeJavaAnnotations(c.getRawAttributes());
- acount += writeTypeAnnotations(c.getRawTypeAttributes());
+ acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
acount += writeEnclosingMethodAttribute(c);
acount += writeExtraClassAttributes(c);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue May 14 15:04:06 2013 -0700
@@ -1010,7 +1010,16 @@
state.pop(((Symbol)(pool.pool[od])).erasure(types));
break;
case new_:
- state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
+ Symbol sym;
+ if (pool.pool[od] instanceof UniqueType) {
+ // Required by change in Gen.makeRef to allow
+ // annotated types.
+ // TODO: is this needed anywhere else?
+ sym = ((UniqueType)(pool.pool[od])).type.tsym;
+ } else {
+ sym = (Symbol)(pool.pool[od]);
+ }
+ state.push(uninitializedObject(sym.erasure(types), cp-3));
break;
case sipush:
state.push(syms.intType);
@@ -1972,25 +1981,38 @@
if (lv == null || lv.sym == null
|| lv.sym.annotations.isTypesEmpty()
|| !lv.sym.isExceptionParameter())
- return;
-
- int exidx = findExceptionIndex(lv);
+ continue;
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
TypeAnnotationPosition p = ta.position;
- p.exception_index = exidx;
+ // At this point p.type_index contains the catch type index.
+ // Use that index to determine the exception table index.
+ // We can afterwards discard the type_index.
+ // A TA position is shared for all type annotations in the
+ // same location; updating one is enough.
+ // Use -666 as a marker that the exception_index was already updated.
+ if (p.type_index != -666) {
+ p.exception_index = findExceptionIndex(p.type_index);
+ p.type_index = -666;
+ }
}
}
}
- private int findExceptionIndex(LocalVar lv) {
+ private int findExceptionIndex(int catchType) {
+ if (catchType == Integer.MIN_VALUE) {
+ // We didn't set the catch type index correctly.
+ // This shouldn't happen.
+ // TODO: issue error?
+ return -1;
+ }
List<char[]> iter = catchInfo.toList();
int len = catchInfo.length();
for (int i = 0; i < len; ++i) {
char[] catchEntry = iter.head;
iter = iter.tail;
- char handlerpc = catchEntry[2];
- if (lv.start_pc == handlerpc + 1) {
+ char ct = catchEntry[3];
+ if (catchType == ct) {
return i;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue May 14 15:04:06 2013 -0700
@@ -30,6 +30,8 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.tree.*;
@@ -47,7 +49,6 @@
import static com.sun.tools.javac.jvm.CRTFlags.*;
import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
/** This pass maps flat Java (i.e. without inner classes) to bytecodes.
*
@@ -308,7 +309,15 @@
*/
int makeRef(DiagnosticPosition pos, Type type) {
checkDimension(pos, type);
- return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ if (type.isAnnotated()) {
+ // Treat annotated types separately - we don't want
+ // to collapse all of them - at least for annotated
+ // exceptions.
+ // TODO: review this.
+ return pool.put((Object)type);
+ } else {
+ return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type);
+ }
}
/** Check if the given type is an array with too many dimensions.
@@ -456,7 +465,9 @@
*/
List<JCTree> normalizeDefs(List<JCTree> defs, ClassSymbol c) {
ListBuffer<JCStatement> initCode = new ListBuffer<JCStatement>();
+ ListBuffer<Attribute.TypeCompound> initTAs = new ListBuffer<Attribute.TypeCompound>();
ListBuffer<JCStatement> clinitCode = new ListBuffer<JCStatement>();
+ ListBuffer<Attribute.TypeCompound> clinitTAs = new ListBuffer<Attribute.TypeCompound>();
ListBuffer<JCTree> methodDefs = new ListBuffer<JCTree>();
// Sort definitions into three listbuffers:
// - initCode for instance initializers
@@ -486,6 +497,7 @@
Assignment(sym, vdef.init);
initCode.append(init);
endPosTable.replaceTree(vdef, init);
+ initTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else if (sym.getConstValue() == null) {
// Initialize class (static) variables only if
// they are not compile-time constants.
@@ -493,6 +505,7 @@
Assignment(sym, vdef.init);
clinitCode.append(init);
endPosTable.replaceTree(vdef, init);
+ clinitTAs.addAll(getAndRemoveNonFieldTAs(sym));
} else {
checkStringConstant(vdef.init.pos(), sym.getConstValue());
}
@@ -505,8 +518,10 @@
// Insert any instance initializers into all constructors.
if (initCode.length() != 0) {
List<JCStatement> inits = initCode.toList();
+ initTAs.addAll(c.annotations.getInitTypeAttributes());
+ List<Attribute.TypeCompound> initTAlist = initTAs.toList();
for (JCTree t : methodDefs) {
- normalizeMethod((JCMethodDecl)t, inits);
+ normalizeMethod((JCMethodDecl)t, inits, initTAlist);
}
}
// If there are class initializers, create a <clinit> method
@@ -524,11 +539,31 @@
JCBlock block = make.at(clinitStats.head.pos()).Block(0, clinitStats);
block.endpos = TreeInfo.endPos(clinitStats.last());
methodDefs.append(make.MethodDef(clinit, block));
+
+ if (!clinitTAs.isEmpty())
+ clinit.annotations.appendUniqueTypes(clinitTAs.toList());
+ if (!c.annotations.getClassInitTypeAttributes().isEmpty())
+ clinit.annotations.appendUniqueTypes(c.annotations.getClassInitTypeAttributes());
}
// Return all method definitions.
return methodDefs.toList();
}
+ private List<Attribute.TypeCompound> getAndRemoveNonFieldTAs(VarSymbol sym) {
+ List<TypeCompound> tas = sym.getRawTypeAttributes();
+ ListBuffer<Attribute.TypeCompound> fieldTAs = new ListBuffer<Attribute.TypeCompound>();
+ ListBuffer<Attribute.TypeCompound> nonfieldTAs = new ListBuffer<Attribute.TypeCompound>();
+ for (TypeCompound ta : tas) {
+ if (ta.position.type == TargetType.FIELD) {
+ fieldTAs.add(ta);
+ } else {
+ nonfieldTAs.add(ta);
+ }
+ }
+ sym.annotations.setTypeAttributes(fieldTAs.toList());
+ return nonfieldTAs.toList();
+ }
+
/** Check a constant value and report if it is a string that is
* too large.
*/
@@ -546,8 +581,9 @@
* @param md The tree potentially representing a
* constructor's definition.
* @param initCode The list of instance initializer statements.
+ * @param initTAs Type annotations from the initializer expression.
*/
- void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode) {
+ void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<TypeCompound> initTAs) {
if (md.name == names.init && TreeInfo.isInitialConstructor(md)) {
// We are seeing a constructor that does not call another
// constructor of the same class.
@@ -581,6 +617,8 @@
md.body.stats = newstats.toList();
if (md.body.endpos == Position.NOPOS)
md.body.endpos = TreeInfo.endPos(md.body.stats.last());
+
+ md.sym.annotations.appendUniqueTypes(initTAs);
}
}
@@ -1527,6 +1565,11 @@
registerCatch(tree.pos(),
startpc, end, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
gaps = gaps.tail;
startpc = gaps.head.intValue();
@@ -1538,6 +1581,11 @@
registerCatch(tree.pos(),
startpc, endpc, code.curPc(),
catchType);
+ if (subCatch.type.isAnnotated()) {
+ // All compounds share the same position, simply update the
+ // first one.
+ subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
+ }
}
}
VarSymbol exparam = tree.param.sym;
@@ -1783,42 +1831,44 @@
result = items.makeStackItem(pt);
}
- private void setTypeAnnotationPositions(int treePos) {
- MethodSymbol meth = code.meth;
+ private void setTypeAnnotationPositions(int treePos) {
+ MethodSymbol meth = code.meth;
+ boolean initOrClinit = code.meth.getKind() == javax.lang.model.element.ElementKind.CONSTRUCTOR
+ || code.meth.getKind() == javax.lang.model.element.ElementKind.STATIC_INIT;
- for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
- if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR
- && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT)
- return;
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+
+ if (!initOrClinit)
+ return;
- for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
+ for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
- ClassSymbol clazz = meth.enclClass();
- for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
- if (!s.getKind().isField())
- continue;
- for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
- if (ta.position.pos == treePos) {
- ta.position.offset = code.cp;
- ta.position.lvarOffset = new int[] { code.cp };
- ta.position.isValidOffset = true;
- }
- }
- }
- }
+ ClassSymbol clazz = meth.enclClass();
+ for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
+ if (!s.getKind().isField())
+ continue;
+
+ for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
+ ta.position.updatePosOffset(code.cp);
+ }
+ }
+ }
public void visitNewClass(JCNewClass tree) {
// Enclosing instances or anonymous classes should have been eliminated
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue May 14 15:04:06 2013 -0700
@@ -25,7 +25,6 @@
package com.sun.tools.javac.main;
-import com.sun.tools.javac.comp.CompileStates;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
@@ -55,6 +54,7 @@
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.*;
+import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.parser.*;
@@ -62,7 +62,6 @@
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.util.Log.WriterKind;
import static com.sun.tools.javac.code.TypeTag.CLASS;
@@ -484,7 +483,7 @@
*/
protected boolean werror;
- /** Switch: is annotation processing requested explitly via
+ /** Switch: is annotation processing requested explicitly via
* CompilationTask.setProcessors?
*/
protected boolean explicitAnnotationProcessingRequested = false;
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue May 14 15:04:06 2013 -0700
@@ -2013,7 +2013,7 @@
/** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
*/
JCExpression creator(int newpos, List<JCExpression> typeArgs) {
- List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
+ List<JCAnnotation> newAnnotations = annotationsOpt(Tag.ANNOTATION);
switch (token.kind) {
case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
@@ -2030,11 +2030,6 @@
}
JCExpression t = qualident(true);
- // handle type annotations for non primitive arrays
- if (newAnnotations.nonEmpty()) {
- t = insertAnnotationsToMostInner(t, newAnnotations, false);
- }
-
int oldmode = mode;
mode = TYPE;
boolean diamondFound = false;
@@ -2068,6 +2063,11 @@
}
mode = oldmode;
if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
+ // handle type annotations for non primitive arrays
+ if (newAnnotations.nonEmpty()) {
+ t = insertAnnotationsToMostInner(t, newAnnotations, false);
+ }
+
JCExpression e = arrayCreatorRest(newpos, t);
if (diamondFound) {
reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
@@ -2092,8 +2092,18 @@
if (newClass.def != null) {
assert newClass.def.mods.annotations.isEmpty();
if (newAnnotations.nonEmpty()) {
+ // Add type and declaration annotations to the new class;
+ // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
+ // will later remove all type annotations and only leave the
+ // declaration annotations.
newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
- newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+ newClass.def.mods.annotations = newAnnotations;
+ }
+ } else {
+ // handle type annotations for instantiations
+ if (newAnnotations.nonEmpty()) {
+ t = insertAnnotationsToMostInner(t, newAnnotations, false);
+ newClass.clazz = t;
}
}
return newClass;
@@ -2987,7 +2997,22 @@
syntaxError(pos, "expected", IDENTIFIER);
name = token.name();
} else {
- name = ident();
+ if (allowThisIdent) {
+ JCExpression pn = qualident(false);
+ if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
+ name = ((JCIdent)pn).name;
+ } else {
+ if ((mods.flags & Flags.VARARGS) != 0) {
+ log.error(token.pos, "varargs.and.receiver");
+ }
+ if (token.kind == LBRACKET) {
+ log.error(token.pos, "array.and.receiver");
+ }
+ return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
+ }
+ } else {
+ name = ident();
+ }
}
if ((mods.flags & Flags.VARARGS) != 0 &&
token.kind == LBRACKET) {
@@ -3526,18 +3551,24 @@
ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
- if (!typeAnnos.isEmpty())
- ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
- else
- ts.append(qualident(true));
+ JCExpression qi = qualident(true);
+ if (!typeAnnos.isEmpty()) {
+ JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+ ts.append(at);
+ } else {
+ ts.append(qi);
+ }
while (token.kind == COMMA) {
nextToken();
typeAnnos = typeAnnotationsOpt();
- if (!typeAnnos.isEmpty())
- ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
- else
- ts.append(qualident(true));
+ qi = qualident(true);
+ if (!typeAnnos.isEmpty()) {
+ JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
+ ts.append(at);
+ } else {
+ ts.append(qi);
+ }
}
return ts.toList();
}
@@ -3601,7 +3632,7 @@
if (token.kind != RPAREN) {
this.allowThisIdent = true;
lastParam = formalParameter(lambdaParameters);
- if (lastParam.name.contentEquals(TokenKind.THIS.name)) {
+ if (lastParam.nameexpr != null) {
this.receiverParam = lastParam;
} else {
params.append(lastParam);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue May 14 15:04:06 2013 -0700
@@ -221,7 +221,7 @@
bad intersection type target for lambda or method reference\n\
{0}
-# 0: type
+# 0: symbol or type
compiler.misc.not.an.intf.component=\
component type {0} is not an interface
@@ -331,29 +331,29 @@
# 0: type, 1: type
compiler.err.duplicate.annotation.missing.container=\
- duplicate annotation, the declaration of {0} does not have a valid {1} annotation
+ duplicate annotation: the declaration of {0} does not have a valid {1} annotation
# 0: type
compiler.err.invalid.repeatable.annotation=\
- duplicate annotation, {0} is annotated with an invalid Repeatable annotation
-
-# 0: type
+ duplicate annotation: {0} is annotated with an invalid Repeatable annotation
+
+# 0: symbol or type
compiler.err.invalid.repeatable.annotation.no.value=\
- duplicate annotation, {0} is not a valid Repeatable, no value element method declared
+ duplicate annotation: {0} is not a valid Repeatable, no value element method declared
# 0: type, 1: number
compiler.err.invalid.repeatable.annotation.multiple.values=\
- duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
+ duplicate annotation: {0} is not a valid Repeatable, {1} value element methods declared
# 0: type
compiler.err.invalid.repeatable.annotation.invalid.value=\
- duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
-
-# 0: type, 1: type, 2: type
+ duplicate annotation: {0} is not a valid Repeatable: invalid value element
+
+# 0: symbol type, 1: type, 2: type
compiler.err.invalid.repeatable.annotation.value.return=\
- duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
-
-# 0: type, 1: symbol
+ duplicate annotation: value element of containing annotation {0} should have type {2}, found {1}
+
+# 0: symbol or type, 1: symbol
compiler.err.invalid.repeatable.annotation.elem.nondefault=\
containing annotation {0} does not have a default value for element {1}
@@ -592,6 +592,12 @@
compiler.err.varargs.and.old.array.syntax=\
legacy array notation not allowed on variable-arity parameter
+compiler.err.varargs.and.receiver =\
+ varargs notation not allowed on receiver parameter
+
+compiler.err.array.and.receiver =\
+ legacy array notation not allowed on receiver parameter
+
compiler.err.variable.not.allowed=\
variable declaration not allowed here
@@ -659,6 +665,7 @@
compiler.err.missing.ret.stmt=\
missing return statement
+# 0: unused
compiler.misc.missing.ret.val=\
missing return value
@@ -983,7 +990,7 @@
compiler.misc.overridden.default=\
method {0} is overridden in {1}
-# 0: symbol, 1: symbol
+# 0: symbol, 1: type or symbol
compiler.misc.redundant.supertype=\
redundant interface {0} is extended by {1}
@@ -1896,11 +1903,10 @@
#####
-# 0: type, 1: file name
+# 0: symbol or type, 1: file name
compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file=\
auxiliary class {0} in {1} should not be accessed from outside its own source file
-
## The first argument ({0}) is a "kindname".
# 0: symbol kind, 1: symbol, 2: symbol
compiler.err.abstract.cant.be.accessed.directly=\
@@ -2185,15 +2191,42 @@
compiler.err.this.as.identifier=\
as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
+# 0: symbol
+compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class=\
+ receiver parameter not applicable for constructor of top-level class
+
# TODO 308: make a better error message
compiler.err.cant.annotate.static.class=\
enclosing static nested class cannot be annotated
+
# TODO 308: make a better error message
+# 0: unused
compiler.err.cant.annotate.nested.type=\
nested type cannot be annotated
+# 0: type, 1: type
+compiler.err.incorrect.receiver.name=\
+ the receiver name does not match the enclosing class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
compiler.err.incorrect.receiver.type=\
- the receiver type does not match the enclosing class type
+ the receiver type does not match the enclosing class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.type=\
+ the receiver type does not match the enclosing outer class type\n\
+ required: {0}\n\
+ found: {1}
+
+# 0: type, 1: type
+compiler.err.incorrect.constructor.receiver.name=\
+ the receiver name does not match the enclosing outer class type\n\
+ required: {0}\n\
+ found: {1}
compiler.err.no.annotations.on.dot.class=\
no annotations are allowed in the type of a class literal
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue May 14 15:04:06 2013 -0700
@@ -42,7 +42,6 @@
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
-import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/**
@@ -807,12 +806,15 @@
public JCModifiers mods;
/** variable name */
public Name name;
+ /** variable name expression */
+ public JCExpression nameexpr;
/** type of the variable */
public JCExpression vartype;
/** variable's initial value */
public JCExpression init;
/** symbol */
public VarSymbol sym;
+
protected JCVariableDecl(JCModifiers mods,
Name name,
JCExpression vartype,
@@ -824,12 +826,27 @@
this.init = init;
this.sym = sym;
}
+
+ protected JCVariableDecl(JCModifiers mods,
+ JCExpression nameexpr,
+ JCExpression vartype) {
+ this(mods, null, vartype, null, null);
+ this.nameexpr = nameexpr;
+ if (nameexpr.hasTag(Tag.IDENT)) {
+ this.name = ((JCIdent)nameexpr).name;
+ } else {
+ // Only other option is qualified name x.y.this;
+ this.name = ((JCFieldAccess)nameexpr).name;
+ }
+ }
+
@Override
public void accept(Visitor v) { v.visitVarDef(this); }
public Kind getKind() { return Kind.VARIABLE; }
public JCModifiers getModifiers() { return mods; }
public Name getName() { return name; }
+ public JCExpression getNameExpression() { return nameexpr; }
public JCTree getType() { return vartype; }
public JCExpression getInitializer() {
return init;
@@ -845,7 +862,7 @@
}
}
- /**
+ /**
* A no-op statement ";".
*/
public static class JCSkip extends JCStatement implements EmptyStatementTree {
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue May 14 15:04:06 2013 -0700
@@ -261,8 +261,6 @@
}
public void printTypeAnnotations(List<JCAnnotation> trees) throws IOException {
- if (trees.nonEmpty())
- print(" ");
for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
printExpr(l.head);
print(" ");
@@ -564,8 +562,10 @@
vartype = ((JCAnnotatedType)vartype).underlyingType;
}
printExpr(((JCArrayTypeTree) vartype).elemtype);
- if (tas != null)
+ if (tas != null) {
+ print(' ');
printTypeAnnotations(tas);
+ }
print("... " + tree.name);
} else {
printExpr(tree.vartype);
@@ -918,6 +918,9 @@
printExprs(tree.typeargs);
print(">");
}
+ if (tree.def != null && tree.def.mods.annotations.nonEmpty()) {
+ printTypeAnnotations(tree.def.mods.annotations);
+ }
printExpr(tree.clazz);
print("(");
printExprs(tree.args);
@@ -948,7 +951,8 @@
int i = 0;
List<List<JCAnnotation>> da = tree.dimAnnotations;
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
- if (da.size() > i) {
+ if (da.size() > i && !da.get(i).isEmpty()) {
+ print(' ');
printTypeAnnotations(da.get(i));
}
print("[");
@@ -958,6 +962,7 @@
}
if (tree.elems != null) {
if (isElemAnnoType) {
+ print(' ');
printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
}
print("[]");
@@ -1264,6 +1269,7 @@
JCAnnotatedType atype = (JCAnnotatedType) elem;
elem = atype.underlyingType;
if (!elem.hasTag(TYPEARRAY)) break;
+ print(' ');
printTypeAnnotations(atype.annotations);
}
print("[]");
@@ -1301,6 +1307,9 @@
public void visitTypeParameter(JCTypeParameter tree) {
try {
+ if (tree.annotations.nonEmpty()) {
+ this.printTypeAnnotations(tree.annotations);
+ }
print(tree.name);
if (tree.bounds.nonEmpty()) {
print(" extends ");
@@ -1379,6 +1388,7 @@
} else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
printBaseElementType(tree);
+ print(' ');
printTypeAnnotations(tree.annotations);
print("[]");
JCExpression elem = array.elemtype;
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue May 14 15:04:06 2013 -0700
@@ -422,8 +422,13 @@
JCVariableDecl t = (JCVariableDecl) node;
JCModifiers mods = copy(t.mods, p);
JCExpression vartype = copy(t.vartype, p);
- JCExpression init = copy(t.init, p);
- return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+ if (t.nameexpr == null) {
+ JCExpression init = copy(t.init, p);
+ return M.at(t.pos).VarDef(mods, t.name, vartype, init);
+ } else {
+ JCExpression nameexpr = copy(t.nameexpr, p);
+ return M.at(t.pos).ReceiverVarDef(mods, nameexpr, vartype);
+ }
}
public JCTree visitWhileLoop(WhileLoopTree node, P p) {
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue May 14 15:04:06 2013 -0700
@@ -204,6 +204,12 @@
return tree;
}
+ public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
+ JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
+ tree.pos = pos;
+ return tree;
+ }
+
public JCSkip Skip() {
JCSkip tree = new JCSkip();
tree.pos = pos;
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue May 14 15:04:06 2013 -0700
@@ -94,6 +94,7 @@
public void visitVarDef(JCVariableDecl tree) {
scan(tree.mods);
scan(tree.vartype);
+ scan(tree.nameexpr);
scan(tree.init);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue May 14 15:04:06 2013 -0700
@@ -148,6 +148,7 @@
public void visitVarDef(JCVariableDecl tree) {
tree.mods = translate(tree.mods);
+ tree.nameexpr = translate(tree.nameexpr);
tree.vartype = translate(tree.vartype);
tree.init = translate(tree.init);
result = tree;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -37,7 +37,7 @@
/** A class for generic linked lists. Links are supposed to be
* immutable, the only exception being the incremental construction of
* lists via ListBuffers. List is the main container class in
- * GJC. Most data structures and algorthms in GJC use lists rather
+ * GJC. Most data structures and algorithms in GJC use lists rather
* than arrays.
*
* <p>Lists are always trailed by a sentinel element, whose head and tail
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -31,9 +31,7 @@
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Names;
/**
* Represents an annotation type.
@@ -92,7 +90,6 @@
* Elements are always public, so no need to filter them.
*/
public AnnotationTypeElementDoc[] elements() {
- Names names = tsym.name.table.names;
List<AnnotationTypeElementDoc> elements = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
if (e.sym != null && e.sym.kind == Kinds.MTH) {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -29,7 +29,6 @@
import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
/**
* Represents an element of an annotation type.
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -28,7 +28,6 @@
import com.sun.javadoc.*;
import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Symbol.*;
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Tue May 14 15:04:06 2013 -0700
@@ -28,14 +28,10 @@
import java.lang.reflect.Modifier;
import java.text.CollationKey;
-import javax.lang.model.type.TypeKind;
-
import com.sun.javadoc.*;
import com.sun.source.util.TreePath;
-import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.util.List;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java Tue May 14 15:04:06 2013 -0700
@@ -34,10 +34,6 @@
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-
-import com.sun.tools.javac.util.Position;
-
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
/**
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,8 @@
package com.sun.tools.javadoc;
-
import javax.tools.JavaFileObject;
-import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.Enter;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Tue May 14 15:04:06 2013 -0700
@@ -26,9 +26,7 @@
package com.sun.tools.javadoc;
import java.io.PrintWriter;
-import java.text.MessageFormat;
import java.util.Locale;
-import java.util.ResourceBundle;
import com.sun.javadoc.*;
import com.sun.tools.javac.util.Context;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Tue May 14 15:04:06 2013 -0700
@@ -25,8 +25,6 @@
package com.sun.tools.javadoc;
-import javax.lang.model.type.TypeKind;
-
import com.sun.javadoc.*;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
@@ -64,12 +62,9 @@
if (env.legacyDoclet) {
t = env.types.erasure(t);
}
- if (considerAnnotations
- && t.isAnnotated()) {
- return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t);
- }
- if (t.isAnnotated()) {
+ if (considerAnnotations &&
+ t.isAnnotated()) {
Type.AnnotatedType at = (Type.AnnotatedType) t;
return new AnnotatedTypeImpl(env, at);
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Tue May 14 15:04:06 2013 -0700
@@ -25,8 +25,6 @@
package com.sun.tools.javadoc;
-import javax.lang.model.type.TypeKind;
-
import com.sun.javadoc.*;
import com.sun.tools.javac.code.Attribute;
--- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java Tue May 14 15:04:06 2013 -0700
@@ -45,7 +45,6 @@
private static final String[][] NEGATED_TEST = NO_TEST;
private static final String[][] TEST = {
// Test for type annotations on Class Extends (ClassExtends.java).
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "MyClass.html",
"extends <a href=\"../typeannos/ClassExtA.html\" title=\"annotation " +
"in typeannos\">@ClassExtA</a> <a href=\"../typeannos/ParameterizedClass.html\" " +
@@ -53,8 +52,6 @@
"../typeannos/ClassExtB.html\" title=\"annotation in typeannos\">" +
"@ClassExtB</a> java.lang.String>"
},
- */
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "MyClass.html",
"implements <a href=\"../typeannos/ClassExtB.html\" title=\"" +
"annotation in typeannos\">@ClassExtB</a> java.lang.CharSequence, " +
@@ -64,8 +61,6 @@
"<a href=\"../typeannos/ClassExtB.html\" title=\"annotation in " +
"typeannos\">@ClassExtB</a> java.lang.String></pre>"
},
- */
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "MyInterface.html",
"extends <a href=\"../typeannos/ClassExtA.html\" title=\"annotation " +
"in typeannos\">@ClassExtA</a> <a href=\"../typeannos/" +
@@ -75,7 +70,6 @@
"<a href=\"../typeannos/ClassExtB.html\" title=\"annotation in " +
"typeannos\">@ClassExtB</a> java.lang.CharSequence</pre>"
},
- */
// Test for type annotations on Class Parameters (ClassParameters.java).
{BUG_ID + FS + "typeannos" + FS + "ExtendsBound.html",
@@ -83,7 +77,6 @@
"href=\"../typeannos/ClassParamA.html\" title=\"annotation in " +
"typeannos\">@ClassParamA</a> java.lang.String></span>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "ExtendsGeneric.html",
"<pre> class <span class=\"strong\">ExtendsGeneric<K extends " +
"<a href=\"../typeannos/ClassParamA.html\" title=\"annotation in " +
@@ -92,7 +85,6 @@
"../typeannos/ClassParamB.html\" title=\"annotation in typeannos\">" +
"@ClassParamB</a> java.lang.String>></span>"
},
- */
{BUG_ID + FS + "typeannos" + FS + "TwoBounds.html",
"<pre> class <span class=\"strong\">TwoBounds<K extends <a href=\"" +
"../typeannos/ClassParamA.html\" title=\"annotation in typeannos\">" +
@@ -119,7 +111,6 @@
},
// Test for type annotations on fields (Fields.java).
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "DefaultScope.html",
"<pre><a href=\"../typeannos/Parameterized.html\" title=\"class in " +
"typeannos\">Parameterized</a><<a href=\"../typeannos/FldA.html\" " +
@@ -127,7 +118,6 @@
"href=\"../typeannos/FldB.html\" title=\"annotation in typeannos\">" +
"@FldB</a> java.lang.String> bothTypeArgs</pre>"
},
- */
{BUG_ID + FS + "typeannos" + FS + "DefaultScope.html",
"<pre><a href=\"../typeannos/FldA.html\" title=\"annotation in " +
"typeannos\">@FldA</a> java.lang.String <a href=\"../typeannos/" +
@@ -147,7 +137,6 @@
"typeannos\">@FldC</a> <a href=\"../typeannos/FldB.html\" title=\"" +
"annotation in typeannos\">@FldB</a> [] array2Deep</pre>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "ModifiedScoped.html",
"<pre>public final <a href=\"../typeannos/Parameterized.html\" " +
"title=\"class in typeannos\">Parameterized</a><<a href=\"../" +
@@ -160,7 +149,6 @@
"title=\"annotation in typeannos\">@FldB</a> java.lang.String> " +
"nestedParameterized</pre>"
},
- */
{BUG_ID + FS + "typeannos" + FS + "ModifiedScoped.html",
"<pre>public final <a href=\"../typeannos/FldA.html\" " +
"title=\"annotation in typeannos\">@FldA</a> java.lang.String[][] " +
@@ -184,7 +172,6 @@
"<pre><a href=\"../typeannos/MRtnA.html\" title=\"annotation in " +
"typeannos\">@MRtnA</a> java.lang.String[][] array2()</pre>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "MtdModifiedScoped.html",
"<pre>public final <a href=\"../typeannos/MtdParameterized.html\" " +
"title=\"class in typeannos\">MtdParameterized</a><<a href=\"../" +
@@ -197,7 +184,6 @@
"MRtnB.html\" title=\"annotation in typeannos\">@MRtnB</a> java." +
"lang.String> nestedMtdParameterized()</pre>"
},
- */
// Test for type annotations on method type parameters (MethodTypeParameters.java).
{BUG_ID + FS + "typeannos" + FS + "UnscopedUnmodified.html",
@@ -205,7 +191,6 @@
"annotation in typeannos\">@MTyParamA</a> java.lang.String>" +
" void methodExtends()</pre>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "UnscopedUnmodified.html",
"<pre><K extends <a href=\"../typeannos/MTyParamA.html\" title=\"" +
"annotation in typeannos\">@MTyParamA</a> <a href=\"../typeannos/" +
@@ -214,13 +199,11 @@
"title=\"annotation in typeannos\">@MTyParamB</a> java.lang.String" +
">> void nestedExtends()</pre>"
},
- */
{BUG_ID + FS + "typeannos" + FS + "PublicModifiedMethods.html",
"<pre>public final <K extends <a href=\"../typeannos/" +
"MTyParamA.html\" title=\"annotation in typeannos\">@MTyParamA</a> " +
"java.lang.String> void methodExtends()</pre>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "PublicModifiedMethods.html",
"<pre>public final <K extends <a href=\"../typeannos/" +
"MTyParamA.html\" title=\"annotation in typeannos\">@MTyParamA</a> " +
@@ -231,7 +214,6 @@
"title=\"annotation in typeannos\">@MTyParamB</a> java.lang.String" +
">> void dual()</pre>"
},
- */
// Test for type annotations on parameters (Parameters.java).
{BUG_ID + FS + "typeannos" + FS + "Parameters.html",
@@ -240,7 +222,6 @@
"ParaParameterized</a><java.lang.String,java.lang.String>" +
" a)</pre>"
},
- /* @ignore 8012173: javadoc does not receive all type annotations information from javac
{BUG_ID + FS + "typeannos" + FS + "Parameters.html",
"<pre>void nestedParaParameterized(<a href=\"../typeannos/" +
"ParaParameterized.html\" title=\"class in typeannos\">" +
@@ -254,7 +235,6 @@
"typeannos/ParamB.html\" title=\"annotation in typeannos\">@ParamB" +
"</a> java.lang.String> a)</pre>"
},
- */
{BUG_ID + FS + "typeannos" + FS + "Parameters.html",
"<pre>void array2Deep(<a href=\"../typeannos/ParamA.html\" " +
"title=\"annotation in typeannos\">@ParamA</a> java.lang.String " +
--- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Tue May 14 15:04:06 2013 -0700
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8006735
- * @summary Smoke test for ensuring that annotations are emited to javadoc
+ * @summary Smoke test for ensuring that annotations are emitted to javadoc
*
* @author Mahmood Ali <mali>
* @library ../../lib/
@@ -46,37 +46,35 @@
//Input for string search tests.
private static final String[][] TEST = {
{BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@DA"},
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@DA"},
- */
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@DA"},
- */
{BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"},
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"},
- */
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"},
- */
/* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"},
*/
/* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+ {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@DTPA"},
+ */
+ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+ {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@DA"},
+ */
+ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x22.html", "@DA"},
*/
+ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+ {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@DTPA"},
+ */
+ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
+ {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@DA"},
+ */
{BUG_ID + FS + "pkg" + FS + "T0x10.html", "@DA"},
{BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@DA"},
{BUG_ID + FS + "pkg" + FS + "T0x12.html", "@DA"},
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x11.html", "@DA"},
- */
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x13.html", "@DA"},
- */
- /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java
{BUG_ID + FS + "pkg" + FS + "T0x15.html", "@DA"},
- */
{BUG_ID + FS + "pkg" + FS + "T0x14.html", "@DA"},
{BUG_ID + FS + "pkg" + FS + "T0x16.html", "@DA"}
};
@@ -94,7 +92,11 @@
{BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x20.html", "@A"},
+ {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@A"},
+ {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x22.html", "@A"},
+ {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@A"},
+ {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x10.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@A"},
{BUG_ID + FS + "pkg" + FS + "T0x12.html", "@A"},
--- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, 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
@@ -36,24 +36,19 @@
* @author Yuri Gaevsky
*/
-@Target({TYPE_USE})
+@Target(TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface A {}
-@Target({TYPE_USE})
+@Target(TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface DA {}
-/** wildcard bound */
-class T0x1C {
- void m0x1C(List<? extends @A @DA String> lst) {}
-}
-
-/** wildcard bound generic/array */
-class T0x1D<T> {
- void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
-}
+@Target(TYPE_PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@interface DTPA {}
/** typecast */
class T0x00 {
@@ -76,6 +71,13 @@
}
}
+/** type test (instanceof) generic/array */
+class T0x03<T> {
+ void m0x03(T typeObj, Object obj) {
+ boolean ok = obj instanceof String @A @DA [];
+ }
+}
+
/** object creation (new) */
class T0x04 {
void m0x04() {
@@ -83,80 +85,22 @@
}
}
-/** local variable */
-class T0x08 {
- void m0x08() {
- @A @DA String s = null;
+/** object creation (new) generic/array */
+class T0x05<T> {
+ void m0x05() {
+ new ArrayList<@A @DA T>();
}
}
-/** method parameter generic/array */
-class T0x0D {
- void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {}
-}
-
/** method receiver */
class T0x06 {
void m0x06(@A @DA T0x06 this) {}
}
-/** method return type generic/array */
-class T0x0B {
- Class<@A @DA Object> m0x0B() { return null; }
-}
-
-/** field generic/array */
-class T0x0F {
- HashMap<@A @DA Object, @A @DA Object> c1;
-}
-
-/** method type parameter */
-class T0x20<T, U> {
- <@A @DA T, @A @DA U> void m0x20() {}
-}
-
-/** class type parameter */
-class T0x22<@A @DA T, @A @DA U> {
-}
-
-/** class type parameter bound */
-class T0x10<T extends @A @DA Cloneable> {
-}
-
-class T0x10A<T extends @A @DA Object> {
-}
-
-/** method type parameter bound */
-class T0x12<T> {
- <T extends @A @DA Cloneable> void m0x12() {}
-}
-
-/** class type parameter bound generic/array */
-class T0x11<T extends List<@A @DA T>> {
-}
-
-/** method type parameter bound generic/array */
-class T0x13 {
- static <T extends Comparable<@A @DA T>> T m0x13() {
- return null;
- }
-}
-
-/** class extends/implements generic/array */
-class T0x15<T> extends ArrayList<@A @DA T> {
-}
-
-/** type test (instanceof) generic/array */
-class T0x03<T> {
- void m0x03(T typeObj, Object obj) {
- boolean ok = obj instanceof String @A @DA [];
- }
-}
-
-/** object creation (new) generic/array */
-class T0x05<T> {
- void m0x05() {
- new ArrayList<@A @DA T>();
+/** local variable */
+class T0x08 {
+ void m0x08() {
+ @A @DA String s = null;
}
}
@@ -171,20 +115,55 @@
}
}
-/** type argument in constructor call generic/array */
-class T0x19 {
- <T> T0x19() {}
+/** method return type generic/array */
+class T0x0B {
+ Class<@A @DA Object> m0x0B() { return null; }
+}
+
+/** method parameter generic/array */
+class T0x0D {
+ void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {}
+}
+
+/** field generic/array */
+class T0x0F {
+ HashMap<@A @DA Object, @A @DA Object> c1;
+}
- void g() {
- new <List<@A @DA String>> T0x19();
+/** class type parameter bound */
+class T0x10<T extends @A @DA Cloneable> {
+}
+
+class T0x10A<T extends @A @DA Object> {
+}
+
+/** class type parameter bound generic/array */
+class T0x11<T extends List<@A @DA T>> {
+}
+
+/** method type parameter bound */
+class T0x12<T> {
+ <T extends @A @DA Cloneable> void m0x12() {}
+}
+
+/** method type parameter bound generic/array */
+class T0x13 {
+ static <T extends Comparable<@A @DA T>> T m0x13() {
+ return null;
}
}
-/** type argument in method call generic/array */
-class T0x1B<T> {
- void m0x1B() {
- Collections.<T @A @DA []>emptyList();
- }
+/** class extends/implements */
+class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable {
+}
+
+/** class extends/implements generic/array */
+class T0x15<T> extends ArrayList<@A @DA T> {
+}
+
+/** exception type in throws */
+class T0x16 {
+ void m0x16() throws @A @DA Exception {}
}
/** type argument in constructor call */
@@ -196,6 +175,15 @@
}
}
+/** type argument in constructor call generic/array */
+class T0x19 {
+ <T> T0x19() {}
+
+ void g() {
+ new <List<@A @DA String>> T0x19();
+ }
+}
+
/** type argument in method call */
class T0x1A<T,U> {
public static <T, U> T m() { return null; }
@@ -204,11 +192,43 @@
}
}
-/** class extends/implements */
-class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable {
+/** type argument in method call generic/array */
+class T0x1B<T> {
+ void m0x1B() {
+ Collections.<T @A @DA []>emptyList();
+ }
+}
+
+/** wildcard bound */
+class T0x1C {
+ void m0x1C(List<? extends @A @DA String> lst) {}
+}
+
+/** wildcard bound generic/array */
+class T0x1D<T> {
+ void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
}
-/** exception type in throws */
-class T0x16 {
- void m0x16() throws @A @DA Exception {}
+/** method type parameter */
+class T0x20 {
+ <@A @DA T> void m0x20() {}
+}
+
+class T0x20A {
+ <@A @DTPA T> void m0x20A() {}
+}
+
+class T0x20B {
+ <T> void m0x20B(@A @DA T p) {}
}
+
+/** class type parameter */
+class T0x22<@A @DA T> {
+}
+
+class T0x22A<@A @DTPA T> {
+}
+
+class T0x22B<T> {
+ @A @DA T f;
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java Tue May 14 15:04:06 2013 -0700
@@ -28,11 +28,17 @@
* @author Mahmood Ali
* @compile Scopes.java
*/
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
class Scopes {
void test(@A(VALUE) Scopes this) { }
void test1(@A(value=VALUE) Scopes this) { }
private static final int VALUE = 1;
+
+ @Target(ElementType.TYPE_USE)
@interface A { int value(); }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java Tue May 14 15:04:06 2013 -0700
@@ -66,12 +66,12 @@
}
ClassFile getClassFile(URL url) throws IOException, ConstantPoolException {
- InputStream in = url.openStream();
- try {
- return ClassFile.read(in);
- } finally {
- in.close();
- }
+ InputStream in = url.openStream();
+ try {
+ return ClassFile.read(in);
+ } finally {
+ in.close();
+ }
}
/************ Helper annotations counting methods ******************/
@@ -83,20 +83,43 @@
test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
}
- void test(ClassFile cf, Method m) {
- test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
- test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
- test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
- test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+ void test(ClassFile cf, Field f, Boolean local) {
+ if (!local) {
+ test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+ test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
+ test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
+ test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+ } else {
+ test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+ test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
+ test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
+ test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+ }
}
void test(ClassFile cf, Field f) {
- test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
- test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
- test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
- test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
+ test(cf, f, false);
}
+ // 'local' determines whether to look for annotations in code attribute or not.
+ void test(ClassFile cf, Method m, Boolean local) {
+ if (!local) {
+ test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+ test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+ test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
+ test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+ } else {
+ test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
+ test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
+ test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
+ test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
+ }
+ }
+
+ // default to not looking in code attribute
+ void test(ClassFile cf, Method m ) {
+ test(cf, m, false);
+ }
// Test the result of Attributes.getIndex according to expectations
// encoded in the class/field/method name; increment annotations counts.
@@ -105,18 +128,47 @@
String name = null;
int index = -1;
Attribute attr = null;
+ Code_attribute cAttr = null;
boolean isTAattr = annName.contains("TypeAnnotations");
try {
switch(testtype) {
case "FIELD":
name = f.getName(cf.constant_pool);
index = f.attributes.getIndex(cf.constant_pool, annName);
- if(index!= -1) attr = f.attributes.get(index);
+ if(index!= -1)
+ attr = f.attributes.get(index);
+ break;
+ case "CODE":
+ name = f.getName(cf.constant_pool);
+ //fetch index of and code attribute and annotations from code attribute.
+ index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = cf.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, annName);
+ if(index!= -1)
+ attr = cAttr.attributes.get(index);
+ }
break;
case "METHOD":
name = m.getName(cf.constant_pool);
index = m.attributes.getIndex(cf.constant_pool, annName);
- if(index!= -1) attr = m.attributes.get(index);
+ if(index!= -1)
+ attr = m.attributes.get(index);
+ break;
+ case "MCODE":
+ name = m.getName(cf.constant_pool);
+ //fetch index of and code attribute and annotations from code attribute.
+ index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = m.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, annName);
+ if(index!= -1)
+ attr = cAttr.attributes.get(index);
+ }
break;
default:
name = cf.getName();
@@ -126,7 +178,6 @@
} catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
if (index != -1) {
- assert attr instanceof RuntimeTypeAnnotations_attribute;
if(isTAattr) { //count RuntimeTypeAnnotations
RuntimeTypeAnnotations_attribute tAttr =
(RuntimeTypeAnnotations_attribute)attr;
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java Tue May 14 15:04:06 2013 -0700
@@ -24,7 +24,6 @@
/*
* @test
* @bug 8005085 8005877 8004829 8005681 8006734 8006775
- * @ignore 8013409: test failures for type annotations
* @summary Combinations of Target ElementTypes on (repeated)type annotations.
*/
@@ -32,10 +31,25 @@
import java.io.File;
public class CombinationsTargetTest1 extends ClassfileTestHelper {
- // Helps identify test case in event of failure.
+
+ // Test count helps identify test case in event of failure.
int testcount = 0;
- int src1 = 1, src2 = 2, src4 = 4,
- src5 = 5, src6 = 6, src7 = 7;
+
+ // Base test case template descriptions
+ enum srce {
+ src1("(repeating) type annotations at class level"),
+ src2("(repeating) type annotations on method"),
+ src3("(repeating) type annotations on wildcard, type arguments in anonymous class"),
+ src4("(repeating) type annotations on type parameters, bounds and type arguments on class decl"),
+ src5("(repeating) type annotations on type parameters, bounds and type arguments on method"),
+ src6("(repeating) type annotations on type parameters, bounds and type arguments in method");
+
+ String description;
+
+ srce(String desc) {
+ this.description = this + ": " +desc;
+ }
+ }
String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
"LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
@@ -52,7 +66,6 @@
// Determines which repeat and order in source(ABMix).
Boolean As= false, BDs=true, ABMix=false;
int testrun=0;
- // A repeats and/or B/D repeats, ABMix for order of As and Bs.
Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
{true,false,false}, //repeat @A
{false,true,false}, //repeat @B
@@ -64,29 +77,29 @@
for(String et : ETypes) {
switch(et) {
case "METHOD":
- test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1);
- test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src2);
- test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src4);
- test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src6);
- test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
- test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src2);
- test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src4);
- test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src6);
+ test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
+ test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src2);
+ test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src3);
+ test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src5);
+ test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+ test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
+ test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
+ test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
break;
case "CONSTRUCTOR":
case "FIELD":
- test( 8, 0, 4, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1);
- test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src5);
- test( 9, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src7);
- test( 0, 8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
- test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5);
- test( 0, 9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src7);
+ test( 8, 0, 4, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
+ test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src4);
+ test( 9, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src6);
+ test( 0, 8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+ test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
+ test( 0, 9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6);
break;
default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
- test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1);
- test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src5);
- test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1);
- test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5);
+ test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
+ test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src4);
+ test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+ test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
}
}
}
@@ -94,7 +107,7 @@
public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
- Integer N, int source) throws Exception {
+ Integer N, srce source) throws Exception {
++testcount;
expected_tvisibles = tvis;
expected_tinvisibles = tinv;
@@ -125,7 +138,8 @@
//if sourcString() set hasInnerClass it also set innerClassname.
if(hasInnerClass) {
StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
- classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
+ classFile=new File(sb.insert(sb.lastIndexOf(".class"),
+ innerClassname).toString());
}
ClassFile cf = ClassFile.read(classFile);
@@ -152,7 +166,7 @@
//
String sourceString(String testname, String retentn, String annot2,
Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
- int src) {
+ srce src) {
String As = "@A", Bs = "@B", Ds = "@D";
if(Arepeats) As = "@A @A";
@@ -201,11 +215,11 @@
"@Retention("+retentn+")\n" +
"@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
- "@interface DC { D[] value(); }\n\n");
+ "@interface DC { D[] value(); }\n");
// Test case sources with sample generated source.
switch(src) {
- case 1: // repeating type annotations at class level
+ case src1: // repeating type annotations at class level
/*
* @A @B class Test1 {
* @A @B Test1(){}
@@ -218,21 +232,21 @@
* }}
*/
source = new String(
- "// (repeating) type annotations at class level. \n" +
- "_As_ _Bs_ class " + testname + " {\n" +
- "_As_ _Bs_ " + testname +"(){} \n" +
- "_As_ _Bs_ Integer i1 = 0; \n" +
- "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
- "// type usage in method body \n" +
- "String test("+testname+" this, " +
- "String param, String ... vararg) { \n" +
- " Object o = new String [3]; \n" +
- " return (String) null; \n" +
- "} \n" +
- "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
- "\n\n";
+ "// " + src.description + "\n" +
+ "_As_ _Bs_ class " + testname + " {\n" +
+ "_As_ _Bs_ " + testname +"(){} \n" +
+ "_As_ _Bs_ Integer i1 = 0; \n" +
+ "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" +
+ "// type usage in method body \n" +
+ "String test("+testname+" this, " +
+ "String param, String ... vararg) { \n" +
+ " Object o = new String [3]; \n" +
+ " return (String) null; \n" +
+ "}\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
break;
- case 2: // (repeating) type annotations on method.
+ case src2: // (repeating) type annotations on method.
/*
* class Test12 {
* Test12(){}
@@ -243,26 +257,26 @@
* }}
*/
source = new String(
- "// (repeating) type annotations on method. \n" +
- "class " + testname + " {\n" +
- testname +"(){} \n" +
- "// type usage on method \n" +
- "_As_ _Bs_ String test(_As_ _Bs_ "+testname+" this, " +
- "_As_ _Bs_ String param, _As_ _Bs_ String _As_ _Bs_ ... vararg) { \n" +
- " Object o = new String [3]; \n" +
- " return (String) null; \n" +
- "} \n" +
- "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
- "\n\n";
+ "// " + src.description + "\n" +
+ "class " + testname + " {\n" +
+ testname +"(){} \n" +
+ "// type usage on method \n" +
+ "_As_ _Bs_ String test(_As_ _Bs_ "+testname+" this, " +
+ "_As_ _Bs_ String param, _As_ _Bs_ String _As_ _Bs_ ... vararg) { \n" +
+ " Object o = new String [3]; \n" +
+ " return (String) null; \n" +
+ "}\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
break;
- case 4: //(repeating) annotations on wildcard, type arguments in anonymous class.
+ case src3: //(repeating) annotations on wildcard, type arguments in anonymous class.
/*
* class Test13<T extends Object> {
* public T data = null;
* T getData() { return data;}
* String mtest( Test13<String> t){ return t.getData(); }
* public void test() {
- * mtest( new Test13<@A @B String>() {
+ * mtest( new Test13<String>() {
* void m1(List<@A @B ? extends @A @B Object> lst) {}
* void m2() throws@A @B Exception { }
* });
@@ -270,22 +284,23 @@
* }
*/
source = new String( source +
- "// (repeating) annotations on wildcard, type arguments in anonymous class. \n" +
- "class " + testname + "<T extends Object> {\n" +
- " public T data = null;\n" +
- " T getData() { return data;}\n" +
- " String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
- " public void test() {\n" +
- " mtest( new " + testname + "<_As_ _Bs_ String>() {\n" +
- " void m1(List<_As_ _Bs_ ? extends _As_ _Bs_ Object> lst) {}\n" +
- " void m2() throws_As_ _Bs_ Exception { }\n" +
- " });\n" +
- " }\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + "\n\n";
- hasInnerClass=true;
- innerClassname="$1";
+ "// " + src.description + "\n" +
+ "class " + testname + "<T extends Object> {\n" +
+ " public T data = null;\n" +
+ " T getData() { return data;}\n" +
+ " String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
+ " public void test() {\n" +
+ " mtest( new " + testname + "<String>() {\n" +
+ " void m1(List<_As_ _Bs_ ? extends _As_ _Bs_ Object> lst) {}\n" +
+ " void m2() throws_As_ _Bs_ Exception { }\n" +
+ " });\n" +
+ " }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ hasInnerClass=true;
+ innerClassname="$1";
break;
- case 5: // (repeating)annotations on type parameters, bounds and type arguments on class decl.
+ case src4: // (repeating)annotations on type parameters, bounds and type arguments on class decl.
/*
* @A @B @D
* class Test2<@A @B @C @D T extends @A @B Object> {
@@ -297,18 +312,18 @@
* }
*/
source = new String( source +
- "// (repeating)annotations on type parameters, bounds and type arguments on class decl. \n" +
- "_As_ _Bs_ _Ds_\n" + //8004829: A and B on type parameter below.
- "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
- " Map<List<String>, Integer> map =\n" +
- " new HashMap<List< String>, Integer>();\n" +
- " Map<List<String>,Integer> map2 = new HashMap<>();\n" +
- " String test(" + testname + "<T> this) { return null;}\n" +
- " <T> String genericMethod(T t) { return null; }\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
- "\n\n";
- break;
- case 6: // (repeating) annotations on type parameters, bounds and type arguments on method.
+ "// " + src.description + "\n" +
+ "_As_ _Bs_ _Ds_\n" + //8004829: A and B on type parameter below.
+ "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" +
+ " Map<List<String>, Integer> map =\n" +
+ " new HashMap<List< String>, Integer>();\n" +
+ " Map<List<String>,Integer> map2 = new HashMap<>();\n" +
+ " String test(" + testname + "<T> this) { return null;}\n" +
+ " <T> String genericMethod(T t) { return null; }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n";
+ break;
+ case src5: // (repeating) annotations on type parameters, bounds and type arguments on method.
/*
* class Test14<T extends Object> {
* Map<List<String>, Integer> map =
@@ -319,17 +334,17 @@
* }
*/
source = new String( source +
- "// (repeating) annotations on type parameters, bounds and type arguments on method. \n" +
- "class " + testname + "<T extends Object> {\n" +
- " Map<List<String>, Integer> map =\n" +
- " new HashMap<List<String>, Integer>();\n" +
- " Map<List<String>, Integer> map2 = new HashMap<>();\n" +
- " String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
- " <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
- "\n\n";
- break;
- case 7: // repeating annotations on type parameters, bounds and type arguments in method.
+ "// " + src.description + "\n" +
+ "class " + testname + "<T extends Object> {\n" +
+ " Map<List<String>, Integer> map =\n" +
+ " new HashMap<List<String>, Integer>();\n" +
+ " Map<List<String>, Integer> map2 = new HashMap<>();\n" +
+ " String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
+ " <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n";
+ break;
+ case src6: // repeating annotations on type parameters, bounds and type arguments in method.
/*
* class Test7{
* <E extends Comparable> Map<List<E>, E > foo(E e) {
@@ -344,22 +359,22 @@
* }
*/
source = new String( source +
- "// (repeating)annotations on type parameters of class, method return value in method. \n" +
- "class "+ testname + "{\n" +
- " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
- " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest
- " Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
- " return new HashMap<List<E>,E>();\n" +
- " }\n" +
- " }\n" +
- " return new maptest<E>().getMap();\n" +
- " }\n" +
- " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
- "\n\n";
- hasInnerClass=true;
- innerClassname="$1maptest";
- break;
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+ " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest
+ " Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
+ " return new HashMap<List<E>,E>();\n" +
+ " }\n" +
+ " }\n" +
+ " return new maptest<E>().getMap();\n" +
+ " }\n" +
+ " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n";
+ hasInnerClass=true;
+ innerClassname="$1maptest";
+ break;
}
return imports + source;
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java Tue May 14 15:04:06 2013 -0700
@@ -23,8 +23,7 @@
/*
* @test
- * @bug 8005085 8005877 8004829 8005681 8006734 8006775
- * @ignore 8013409: test failures for type annotations
+ * @bug 8005085 8005877 8004829 8005681 8006734 8006775 8006507
* @summary Combinations of Target ElementTypes on (repeated)type annotations.
*/
@@ -32,9 +31,27 @@
import java.io.File;
public class CombinationsTargetTest2 extends ClassfileTestHelper {
- // Helps identify test case in event of failure.
+
+ // Test count helps identify test case in event of failure.
int testcount = 0;
- int src3 = 3, src8 = 8, src9 = 9;
+
+ // Base test case template descriptions
+ enum srce {
+ src1("(repeating) type annotations on on field in method body",true),
+ src2("(repeating) type annotations on type parameters, bounds and type arguments", true),
+ src3("(repeating) type annotations on type parameters of class, method return value in method", true),
+ src4("(repeating) type annotations on field in anonymous class", false),
+ src5("(repeating) type annotations on field in anonymous class", false);
+
+ String description;
+ Boolean local;
+
+ srce(String desc, Boolean b) {
+ this.description = this + ": " +desc;
+ this.local = b;
+ }
+ }
+
String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
"LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"};
@@ -51,31 +68,36 @@
// Determines which repeat and order in source(ABMix).
Boolean As= false, BDs=true, ABMix=false;
int testrun=0;
- // A repeats and/or B/D repeats, ABMix for order of As and Bs.
Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats
{true,false,false}, //repeat @A
{false,true,false}, //repeat @B
{true,true,false}, //repeat both
{false,false,true} //repeat mix
};
+
for(Boolean[] bCombo : bRepeat) {
As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
for(String et : ETypes) {
switch(et) {
case "METHOD":
- test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src3);
- test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3);
+ test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
+ test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+ test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src5);
+ test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
break;
- case "CONSTRUCTOR":
case "FIELD":
- test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src3);
- test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src8);
- test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src9);
- test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3);
- test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src8);
- test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src9);
+ test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
+ test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src2);
+ test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src3);
+ test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src4);
+ test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
+ test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src2);
+ test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src3);
+ test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
break;
default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/
+ test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src4);
+ test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
break;
}
}
@@ -84,7 +106,7 @@
public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
- Integer N, int source) throws Exception {
+ Integer N, srce source) throws Exception {
++testcount;
expected_tvisibles = tvis;
expected_tinvisibles = tinv;
@@ -97,14 +119,19 @@
", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
- et2 + ", src=" + source;
+ et2 + ", src=" + source + "\n " + source.description;
-// Uncomment this block to run the tests but skip failing scenarios.
-// // 8005681 - skip cases with repeated annotations on new, array, cast.
-// if((source==3 || source==8 || source==9) && (ABmix || (Arepeats && BDrepeats))) {
-// System.out.println(testDef+"\n8005681-skip repeated annotations on new,array,cast");
-// return;
-// }
+ if(
+// 8005681 - src1,2,3 - skip cases with repeated annotations on new, array, cast.
+ (( source.equals(srce.src1) || source.equals(srce.src2) ||
+ source.equals(srce.src3)) && (ABmix || (Arepeats && BDrepeats)))
+ // 8008928 - src4,5 - this change cause crash with t-a on anon class)
+ || (source.equals(srce.src4) || source.equals(srce.src5))
+ ) {
+ System.out.println(testDef +
+ "\n 8005681-skip repeated annotations on new,array,cast");
+ return;
+ }
println(testDef);
// Create test source and File.
@@ -123,6 +150,7 @@
if(hasInnerClass) {
StringBuffer sb = new StringBuffer(classFile.getAbsolutePath());
classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
+ println("classfile: " + classFile.getAbsolutePath());
}
ClassFile cf = ClassFile.read(classFile);
@@ -130,10 +158,16 @@
test(cf);
for (Field f : cf.fields) {
- test(cf, f);
+ if(source.local)
+ test(cf, f, true);
+ else
+ test(cf,f);
}
for (Method m: cf.methods) {
- test(cf, m);
+ if(source.local)
+ test(cf, m, true);
+ else
+ test(cf, m);
}
countAnnotations();
if (errors > 0) {
@@ -149,7 +183,7 @@
//
String sourceString(String testname, String retentn, String annot2,
Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
- int src) {
+ srce src) {
String As = "@A", Bs = "@B", Ds = "@D";
if(Arepeats) As = "@A @A";
@@ -198,7 +232,7 @@
// Test case sources with sample generated source
switch(src) {
- case 3: // (repeating) type annotations on field in method body
+ case src1: // (repeating) type annotations on field in method body
/*
* class Test1 {
* Test1(){}
@@ -210,18 +244,19 @@
* }}
*/
source = new String(
- "class " + testname + " {\n" +
- "" + testname +"(){} \n" +
- "// type usage in method body \n" +
- "String test("+testname+" this, " +
- "String param, String ... vararg) { \n" +
- " _As_ _Bs_\n Object o = new _As_ _Bs_ String _As_ _Bs_ [3]; \n" +
- " return (_As_ _Bs_ String) null; \n" +
- "} \n" +
- "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
- "\n\n";
- break;
- case 8: // (repeating) annotations on type parameters, bounds and type arguments in new statement.
+ "// " + src.description + "\n" +
+ "class " + testname + " {\n" +
+ "" + testname +"(){} \n" +
+ "// type usage in method body \n" +
+ "String test("+testname+" this, " +
+ "String param, String ... vararg) { \n" +
+ " _As_ _Bs_\n Object o = new _As_ _Bs_ String _As_ _Bs_ [3]; \n" +
+ " return (_As_ _Bs_ String) null; \n" +
+ "} \n" +
+ "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ break;
+ case src2: // (repeating) annotations on type parameters, bounds and type arguments in new statement.
/*
* class Test2<T extends Object> {
* Map<List<String>, Integer> map =
@@ -232,17 +267,17 @@
* }
*/
source = new String( source +
- "// (repeating) annotations on type parameters, bounds and type arguments. \n" +
- "class " + testname + "<T extends Object> {\n" +
- " Map<List<String>, Integer> map =\n" +
- " new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
- " Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
- " String test(" + testname + "<T> this) { return null;}\n" +
- " <T> String genericMethod(T t) { return null; }\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
- "\n\n";
- break;
- case 9: // (repeating)annotations on type parameters of class, method return value in method.
+ "// " + src.description + "\n" +
+ "class " + testname + "<T extends Object> {\n" +
+ " Map<List<String>, Integer> map =\n" +
+ " new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
+ " Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
+ " String test(" + testname + "<T> this) { return null;}\n" +
+ " <T> String genericMethod(T t) { return null; }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ break;
+ case src3: // (repeating)annotations on type parameters of class, method return value in method.
/*
* class Test3{
* <E extends Comparable> Map<List<E>, E > foo(E e) {
@@ -258,24 +293,72 @@
* }
*/
source = new String( source +
- "// (repeating)annotations on type parameters of class, method return value in method. \n" +
- "class "+ testname + "{\n" +
- " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
- " class maptest <E> {\n" + // inner class $1maptest
- " Map<List<E>,E> getMap() { \n" +
- " Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
- " return Em;\n" +
- " }\n" +
- " }\n" +
- " return new maptest<E>().getMap();\n" +
- " }\n" +
- " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
- "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
- "\n\n";
- hasInnerClass=true;
- innerClassname="$1maptest";
- break;
-
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+ " class maptest <E> {\n" + // inner class $1maptest
+ " Map<List<E>,E> getMap() { \n" +
+ " Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
+ " return Em;\n" +
+ " }\n" +
+ " }\n" +
+ " return new maptest<E>().getMap();\n" +
+ " }\n" +
+ " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1maptest";
+ break;
+ case src4: // (repeating)annotations on field in anonymous class
+ /*
+ * class Test95{
+ * void mtest( Test95 t){ }
+ * public void test() {
+ * mtest( new Test95() {
+ * @A @A @B @B String data2 = "test";
+ * });
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " void mtest( "+ testname + " t){ }\n" +
+ " public void test() {\n" +
+ " mtest( new "+ testname + "() {\n" +
+ " _As_ _Bs_ String data2 = \"test\";\n" +
+ " });\n" +
+ " }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1";
+ break;
+ case src5: // (repeating)annotations on method in anonymous class
+ /*
+ * class Test120{
+ * void mtest( Test120 t){ }
+ * public void test() {
+ * mtest( new Test120() {
+ * @A @B @A @B String m2(){return null;};
+ * });
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " void mtest( "+ testname + " t){ }\n" +
+ " public void test() {\n" +
+ " mtest( new "+ testname + "() {\n" +
+ " _As_ _Bs_ String m2(){return null;};\n" +
+ " });\n" +
+ " }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1";
+ break;
}
return imports + source;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8005085 8005681 8008769 8010015
+ * @summary Check (repeating)type annotations on lambda usage.
+ * @run main CombinationsTargetTest3
+ */
+
+import com.sun.tools.classfile.*;
+import java.io.File;
+import java.util.Vector;
+
+public class CombinationsTargetTest3 extends ClassfileTestHelper {
+
+ // Helps identify test case in event of failure.
+ int testcount = 0;
+
+ // Known failure cases due to open bugs.
+ Vector<String> skippedTests = new Vector<>();
+ void printSkips() {
+ if(!skippedTests.isEmpty()) {
+ println(skippedTests.size() + " tests were skipped:");
+ for(String t : skippedTests)
+ println(" " + t);
+ }
+ }
+
+ // Test case descriptions and expected annotation counts.
+ enum srce {
+ src1("type annotations on lambda expression as method arg.",4,0),
+ src2("type annotations on new in single line lambda expression",2,0),
+ src3("type annotations in lambda expression code block",4,0),
+ src4("type annotations in code block with recursion,cast",2,0),
+ src5("type annotations in lambda expression code block",4,0),
+ src6("type annotations on type parm in method reference",4,0),
+ src7("type annotations on inner class field of lambda expression",2,2),
+ src8("type annotations in inner class of lambda expression",4,2),
+ src9("type annotations on static method of interface",4,2);
+
+ String description;
+ // Expected annotation counts are same for Vis or Invis, but which one
+ // depends on retention type.
+ Integer[] exp = { 0, 0 };
+
+ // If class to test is inner class, this may be set in SourceString()
+ String innerClassname = null ;
+
+ // If class to test is not main or inner class; set in sourceString()
+ String altClassName = null;
+
+ srce(String desc, int e1, int e2) {
+ description = this + ": " +desc;
+ exp[0]=e1;
+ exp[1]=e2;
+ }
+ }
+
+ // Check for RuntimeInvisible or RuntimeVisible annotations.
+ String[] RType={"CLASS", "RUNTIME"};
+
+ // This can be a compile only test.
+ static boolean compileonly=false;
+
+ // Collect failure for end of test report()
+ Vector<String> vFailures = new Vector<>();
+
+ // pass/fail determined after all tests have run.
+ void report() {
+ if(vFailures.isEmpty()) {
+ printSkips();
+ println("PASS");
+ } else {
+ System.err.println("FAILED: There were failures:");
+ for(String f : vFailures)
+ System.err.println(f);
+ throw new RuntimeException("There were failures. See test log.");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if(args.length>0 && args[0].compareTo("compileonly")==0)
+ compileonly=true;
+ new CombinationsTargetTest3().run();
+ }
+
+ void run() throws Exception {
+ // Determines which repeat and order in source(ABMix).
+ Boolean As= false, BDs=true, ABMix=false;
+ int testrun=0;
+ // A repeats and/or B/D repeats, ABMix for order of As and Bs.
+ Boolean [][] bRepeat = new Boolean[][]{{false,false,false}, //no repeats
+ {true,false,false}, //repeat @A
+ {false,true,false}, //repeat @B
+ {true,true,false}, //repeat both
+ {false,false,true} //repeat mix
+ };
+ // Added ElementType's. All set; not permuted (so far) for this test
+ String et = "TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE";
+
+ // test loop
+ for(Boolean[] bCombo : bRepeat) {
+ As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2];
+ for(srce src : srce.values())
+ for( String rtype : RType ) {
+ switch( rtype ) {
+ case "RUNTIME":
+ test(0,src.exp[0],0,src.exp[1],As, BDs, ABMix,
+ "RUNTIME", et, ++testrun, src);
+ break;
+ case "CLASS":
+ test(src.exp[0],0,src.exp[1],0,As, BDs, ABMix,
+ "CLASS", et, ++testrun, src);
+ break;
+ }
+ }
+ }
+ report();
+ }
+
+ // Filter out skipped cases, compile, pass class file to test method,
+ // count annotations and asses results.
+ public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats,
+ Boolean BDrepeats, Boolean ABmix, String rtn, String et2,
+ Integer N, srce source) throws Exception {
+ ++testcount;
+ expected_tvisibles = tvis;
+ expected_tinvisibles = tinv;
+ expected_visibles = vis;
+ expected_invisibles = inv;
+ File testFile = null;
+ String tname="Test" + N.toString();
+ String testDef = "Test " + testcount + " parameters: tinv=" + tinv +
+ ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis +
+ ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats +
+ ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
+ et2 + ", src=" + source;
+
+ // Skip failing cases with bug ID's
+ if ((source.equals(srce.src2) || source.equals(srce.src4) ||
+ source.equals(srce.src5)) &&
+ (ABmix || (Arepeats && BDrepeats))) {
+ skippedTests.add(testDef +
+ "\n--8005681 repeated type-annotations on new/cast/array in" +
+ " inner class in lambda expression.");
+ return;
+ }//8008769 Repeated type-annotations on type parm of local variable
+ else if (source.equals(srce.src6) &&
+ (ABmix || (Arepeats && BDrepeats))) {
+ skippedTests.add(testDef + "\n--8008769 Repeated " +
+ "type-annotations on type parm of local variable");
+ return;
+ }
+
+ println(testDef);
+ // Create test source and File.
+ String sourceString = sourceString(tname, rtn, et2, Arepeats,
+ BDrepeats, ABmix, source);
+ testFile = writeTestFile(tname+".java", sourceString);
+ // Compile test source and read classfile.
+ File classFile = null;
+ try {
+ classFile = compile(testFile);
+ System.out.println("pass compile: " + tname + ".java");
+ } catch (Error err) {
+ System.err.println("fail compile. Source:\n" + sourceString);
+ throw err;
+ }
+ if(!compileonly) {
+ //check if innerClassname is set
+ String classdir = classFile.getAbsolutePath();
+ if(source.innerClassname != null) {
+ StringBuffer sb = new StringBuffer(classdir);
+ classFile=new File(sb.insert(sb.lastIndexOf(".class"),
+ source.innerClassname).toString());
+ source.innerClassname=null;
+ } else if (source.altClassName != null) {
+ classdir = classdir.substring(0,classdir.lastIndexOf("Test"));
+ classFile=new File(classdir.concat(source.altClassName));
+ source.innerClassname=null;
+ }
+ ClassFile cf = ClassFile.read(classFile);
+
+ println("Testing classfile: " + cf.getName());
+ //Test class,fields and method counts.
+ test(cf);
+
+ for (Field f : cf.fields) {
+ test(cf, f);
+ test(cf, f, true);
+ }
+ for (Method m: cf.methods) {
+ test(cf, m);
+ test(cf, m, true);
+ }
+
+ countAnnotations(); // sets errors=0 before counting.
+ if (errors > 0) {
+ System.err.println( testDef );
+ System.err.println( "Source:\n" + sourceString );
+ vFailures.add(testDef);
+ }
+ }
+ if(errors==0) println("Pass"); println("");
+ }
+
+ /*
+ * Source definitions for test cases.
+ * To add a test:
+ * Add enum to srce(near top of file) with expected annotation counts.
+ * Add source defintion below.
+ */
+ String sourceString(String testname, String retentn, String annot2,
+ Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
+ srce src) {
+
+ String As = "@A", Bs = "@B", Ds = "@D";
+ if(Arepeats) As = "@A @A";
+ if(BDrepeats) {
+ Bs = "@B @B";
+ Ds = "@D @D";
+ }
+ if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; }
+
+ // Source to check for TYPE_USE and TYPE_PARAMETER annotations.
+ // Source base (annotations) is same for all test cases.
+ String source = new String();
+ String imports = new String("import java.lang.annotation.*; \n" +
+ "import static java.lang.annotation.RetentionPolicy.*; \n" +
+ "import static java.lang.annotation.ElementType.*; \n" +
+ "import java.util.List; \n" +
+ "import java.util.ArrayList;\n\n");
+
+ String sourceBase = new String(
+ "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( AC.class ) @interface A { }\n" +
+ "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface AC { A[] value(); } \n" +
+ "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( BC.class ) @interface B { }\n" +
+ "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface BC { B[] value(); } \n" +
+ "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @Repeatable(DC.class) @interface D { }\n" +
+ "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @interface DC { D[] value(); }");
+
+ // Test case sources with sample generated source
+ switch(src) {
+ case src1: //(repeating) type annotations on lambda expressions.
+ /*
+ * class Test1 {
+ * Test1(){}
+ * interface MapFun<T,R> { R m( T n); }
+ * void meth( MapFun<String,Integer> mf ) {
+ * assert( mf.m("four") == 4);
+ * }
+ * void test(Integer i) {
+ * // lambda expression as method arg
+ * meth( (@A @B String s) -> { @A @B Integer len = s.length(); return len; } );
+ * }}
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class " + testname + " {\n" +
+ " " + testname +"(){} \n" +
+ " interface MapFun<T,R> { R m( T n); }\n\n" +
+ " void meth( MapFun<String,Integer> mf ) {\n" +
+ " assert( mf.m(\"four\") == 4);\n" +
+ " }\n\n" +
+ " void test(Integer i) {\n" +
+ " // lambda expression as method arg\n" +
+ " meth( (_As_ _Bs_ String s) -> { _As_ _Bs_ Integer len = s.length(); return len; } );\n" +
+ "}}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ break;
+ case src2: //(repeating) type annotations on new in single line lambda expression.
+ /*
+ * //case2: (repeating) type annotations on new in single lambda expressions.
+ * class Test2{
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<Integer, String> its;
+ * void test(Integer i) {
+ * its = a -> "~"+new @A @B Integer(a).toString()+"~";
+ * System.out.println("in: " + i + " out: " + its.m(i));
+ * }}
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class " + testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<Integer, String> its;\n" +
+ " void test(Integer i) {\n" +
+ " its = a -> \"~\"+new _As_ _Bs_ Integer(a).toString()+\"~\";\n" +
+ " System.out.println(\"in: \" + i + \" out: \" + its.m(i));\n" +
+ " }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ break;
+ case src3: //(repeating) type annotations in lambda expression code block.
+ /*
+ * class Test183{
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<List<Integer>, String> iLs;
+ * void testm(Integer i) {
+ * iLs = l -> { @A @B @A @B String ret = new String();
+ * for( @A @B @A @B Integer i2 : l)
+ * ret=ret.concat(i2.toString() + " ");
+ * return ret; };
+ * List<Integer> li = new ArrayList<>();
+ * for(int j=0; j<i; j++) li.add(j);
+ * System.out.println(iLs.m(li) );
+ * }}
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<List<Integer>, String> iLs;\n" +
+ " void testm(Integer i) {\n" +
+ " iLs = l -> { _As_ _Bs_ String ret = new String();\n" +
+ " for( _As_ _Bs_ Integer i2 : l)\n" +
+ " ret=ret.concat(i2.toString() + \" \");\n" +
+ " return ret; };\n" +
+ " List<Integer> li = new ArrayList<>();\n" +
+ " for(int j=0; j<i; j++) li.add(j);\n" +
+ " System.out.println(iLs.m(li) );\n" +
+ "}\n" +
+ "\n" +
+ " public static void main(String... args) {new " + testname + "().testm(5); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ break;
+ case src4: //(repeating) type annotations in code block with recursion,cast
+ /*
+ * class Test194{
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<Integer, Double> nf;
+ * void testm(Integer i) {
+ * nf = j -> { return j == 1 ? 1.0 : (@A @B @A @B Double)(nf.m(j-1) * j); };
+ * System.out.println( "nf.m(" + i + "): " + nf.m(i));
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<Integer, Double> nf;\n" +
+ " void testm(Integer i) {\n" +
+ " nf = j -> { return j == 1 ? 1.0 : (_As_ _Bs_ Double)(nf.m(j-1) * j); };\n" +
+ " System.out.println( \"nf.m(\" + i + \"): \" + nf.m(i));\n" +
+ " }\n" +
+ " public static void main(String... args) {new " + testname + "().testm(5); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ break;
+ case src5: //(repeating) type annotations in lambda expression code block.
+ /*
+ * class Test180 {
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<Integer,List<Integer>> iLi;
+ * void test(Integer i) {
+ * // type parameter use.
+ * iLi = n -> { List<@A @B @A @B Integer> LI = new ArrayList<@A @B @A @B Integer>(n);
+ * for(int nn = n; nn >=0; nn--) LI.add(nn);
+ * return LI; };
+ * List<Integer> li = iLi.m(i);
+ * for(Integer k : li) System.out.print(k);
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<Integer,List<Integer>> iLi;\n" +
+ " void test(Integer i) {\n" +
+ " // type parameter use.\n" +
+ " iLi = n -> { List<_As_ _Bs_ Integer> LI = new ArrayList<_As_ _Bs_ Integer>(n);\n" +
+ " for(int nn = n; nn >=0; nn--) LI.add(nn);\n" +
+ " return LI; };\n" +
+ " List<Integer> li = iLi.m(i);\n" +
+ " for(Integer k : li) System.out.print(k);\n" +
+ "}\n" +
+ " public static void main(String... args) {new " + testname + "().test(5); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n";
+ break;
+ case src6: //(repeating) type annotations on type parm in method reference.
+ /*
+ * class Test240{
+ * interface PrintString { void print(String s); }
+ * public void printArray(Object[] oa, PrintString ps) {
+ * for(Object o : oa ) ps.print(o.toString());
+ * }
+ * public void test() {
+ * Integer[] intarray = {1,2,3,4,5};
+ * printArray(intarray, @A @B @A @B TPrint::<@A @B @A @B String>print);
+ * }
+ * }
+ * class TPrint {
+ * public static <T> void print(T t) { System.out.println( t.toString()); }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface PrintString { void print(String s); }\n" +
+ " public void printArray(Object[] oa, PrintString ps) {\n" +
+ " for(Object o : oa ) ps.print(o.toString());\n" +
+ " }\n" +
+ " public void test() {\n" +
+ " Integer[] intarray = {1,2,3,4,5};\n" +
+ " printArray(intarray, _As_ _Bs_ TPrint::<_As_ _Bs_ String>print);\n" +
+ " }\n" +
+ " public static void main(String... args) {new " + testname + "().test(); }\n" +
+ "}\n\n" +
+ "class TPrint {\n" +
+ " public static <T> void print(T t) { System.out.println( t.toString()); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ break;
+ case src7: //(repeating)type annotations in inner class of lambda expression.
+ /*
+ * class Test2{
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<Class<?>,String> cs;
+ * void test() {
+ * cs = c -> {
+ * class innerClass {
+ * @A @B Class<?> icc = null;
+ * String getString() { return icc.toString(); }
+ * }
+ * return new innerClass().getString();
+ * };
+ * System.out.println("cs.m : " + cs.m(Integer.class));
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<Class<?>,String> cs;\n" +
+ " void test() {\n" +
+ " cs = c -> {\n" +
+ " class innerClass {\n" +
+ " _As_ _Bs_ Class<?> icc = null;\n" +
+ " innerClass(Class<?> _c) { icc = _c; }\n" +
+ " String getString() { return icc.toString(); }\n" +
+ " }\n" +
+ " return new innerClass(c).getString();\n" +
+ " };\n" +
+ " System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String... args) {new " + testname + "().test(); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ src.innerClassname="$1innerClass";
+ break;
+ case src8: //(repeating)type annotations in inner class of lambda expression.
+ /*
+ * class Test2{
+ * interface MapFun<T, R> { R m( T n); }
+ * MapFun<Class<?>,String> cs;
+ * void test() {
+ * cs = c -> {
+ * class innerClass {
+ * Class<?> icc;
+ * innerClass(@A @B Class<?> _c) { icc = _c; }
+ * @A @B String getString() { return icc.toString(); }
+ * }
+ * return new innerClass(c).getString();
+ * };
+ * System.out.println("cs.m : " + cs.m(Integer.class));
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface MapFun<T, R> { R m( T n); }\n" +
+ " MapFun<Class<?>,String> cs;\n" +
+ " void test() {\n" +
+ " cs = c -> {\n" +
+ " class innerClass {\n" +
+ " Class<?> icc;\n" +
+ " innerClass(_As_ _Bs_ Class<?> _c) { icc = _c; }\n" +
+ " _As_ _Bs_ String getString() { return icc.toString(); }\n" +
+ " }\n" +
+ " return new innerClass(c).getString();\n" +
+ " };\n" +
+ " System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String... args) {new " + testname + "().test(); }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ src.innerClassname="$1innerClass";
+ break;
+ case src9: //(repeating)type annotations on static method of interface
+ /*
+ * class Test90{
+ * interface I {
+ * static @A @B @A @B String m() { @A @B @A @B String ret = "I.m"; return ret; }
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " interface I { \n" +
+ " static _As_ _Bs_ String m() { _As_ _Bs_ String ret = \"I.m\"; return ret; }\n" +
+ " }\n" +
+ "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n";
+ src.innerClassname="$I";
+ break;
+ }
+ return imports + source;
+ }
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java Tue May 14 15:04:06 2013 -0700
@@ -49,7 +49,7 @@
test(cf, f);
}
for (Method m: cf.methods) {
- test(cf, m);
+ test(cf, m, true);
}
countAnnotations();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -48,7 +48,7 @@
test(cf, f);
}
for (Method m: cf.methods) {
- test(cf, m);
+ test(cf, m, true);
}
countAnnotations();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2013, 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
+ * @bug 8008762
+ * @ignore 8013409: test failures for type annotations
+ * @summary Type annotation on inner class in anonymous class
+ * shows up as regular annotation
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+import com.sun.tools.classfile.*;
+
+public class T8008762 extends ClassfileTestHelper{
+ public static void main(String[] args) throws Exception {
+ new T8008762().run();
+ }
+
+ public void run() throws Exception {
+ expected_tinvisibles = 0;
+ expected_tvisibles = 4;
+
+ ClassFile cf = getClassFile("T8008762$Test$1$InnerAnon.class");
+ test(cf);
+ for (Field f : cf.fields) {
+ test(cf, f, false);
+ }
+ for (Method m : cf.methods) {
+ test(cf, m, false);
+ }
+ countAnnotations();
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ System.out.println("PASSED");
+ }
+
+ /*********************** Test class *************************/
+ static class Test {
+ Object mtest( Test t){ return null; }
+ public void test() {
+ mtest( new Test() {
+ class InnerAnon { // Test1$1$InnerAnon.class
+ @A @B String ai_data = null;
+ @A @B String ai_m(){ return null; };
+ }
+ InnerAnon IA = new InnerAnon();
+ });
+ }
+ @Retention(RUNTIME) @Target(TYPE_USE) @interface A { }
+ @Retention(RUNTIME) @Target(TYPE_USE) @interface B { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8008769.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 2013, 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 Repeated type-annotations on type parm of local variable
+ * are not written to classfile.
+ * @bug 8008769
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import com.sun.tools.classfile.*;
+
+public class T8008769 extends ClassfileTestHelper{
+ public static void main(String[] args) throws Exception {
+ new T8008769().run();
+ }
+
+ public void run() throws Exception {
+ expected_tvisibles = 4;
+ ClassFile cf = getClassFile("T8008769$Test.class");
+ for (Method m : cf.methods) {
+ test(cf, m, true);
+ }
+ countAnnotations();
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ System.out.println("PASSED");
+ }
+
+ /*********************** Test class *************************/
+ static class Test<T> {
+ public void test() {
+ Test<@A @B String> t0 = new Test<>(); // 2 ok
+ Test<@B @B String> t1 = new Test<>(); // 1 missing
+ Test<@A @A @A String> t2 = new Test<>(); // 1 missing
+ }
+ }
+ @Retention(RUNTIME) @Target(TYPE_USE) @Repeatable( AC.class ) @interface A { }
+ @Retention(RUNTIME) @Target(TYPE_USE) @Repeatable( BC.class ) @interface B { }
+ @Retention(RUNTIME) @Target(TYPE_USE) @interface AC { A[] value(); }
+ @Retention(RUNTIME) @Target(TYPE_USE) @interface BC { B[] value(); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/T8010015.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2013, 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 Wrong classfile attribution in inner class of lambda expression.
+ * @bug 8010015
+ */
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import com.sun.tools.classfile.*;
+
+/*
+ * A type-annotations on a field in an inner class not in a lambda expression
+ * results in RuntimeTypeAnnotations_attibute and RuntimeAnnotations_attribute.
+ * On a field in an innner class in a lambda expression, it leaves off the
+ * RuntimeAnnotations_attribute.
+ */
+public class T8010015 extends ClassfileTestHelper{
+ public static void main(String[] args) throws Exception {
+ new T8010015().run();
+ }
+
+ public void run() throws Exception {
+ expected_tvisibles = 1;
+ expected_visibles = 1;
+ ClassFile cf = getClassFile("T8010015$Test$1innerClass.class");
+ for (Field f : cf.fields) {
+ test(cf, f);
+ }
+ countAnnotations();
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ System.out.println("PASSED");
+ }
+
+ /*********************** Test class **************************/
+ interface MapFun<T, R> { R m( T n); }
+ static class Test {
+ MapFun<Class<?>,String> cs;
+ void test() {
+ cs = c -> {
+ class innerClass {
+ @A Class<?> icc = null;
+ innerClass(Class<?> _c) { icc = _c; }
+ String getString() { return icc.toString(); }
+ }
+ return new innerClass(c).getString();
+ };
+ System.out.println("cs.m : " + cs.m(Integer.class));
+ }
+
+ public static void main(String... args) {new Test().test(); }
+ }
+ @Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2013 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
+ * @bug 8005681
+ * @summary Repeated annotations on new,array,cast.
+ */
+import java.lang.annotation.*;
+import java.io.*;
+import java.util.List;
+import com.sun.tools.classfile.*;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+public class TestNewCastArray {
+ int errors = 0;
+ List<String> failedTests = new java.util.LinkedList<>();
+
+ // 'b' tests fail with only even numbers of annotations (8005681).
+ String[] testclasses = {"Test1",
+ "Test2a", "Test3a", "Test4a", "Test5a",
+ "Test2b", "Test3b", "Test4b", "Test5b"
+ };
+
+ public static void main(String[] args) throws Exception {
+ new TestNewCastArray().run();
+ }
+
+ void check(String testcase, int expected, int actual) {
+ String res = testcase + ": (expected) " + expected + ", " + actual + " (actual): ";
+ if(expected == actual) {
+ res = res.concat("PASS");
+ } else {
+ errors++;
+ res = res.concat("FAIL");
+ failedTests.add(res);
+ }
+ System.out.println(res);
+ }
+
+ void report() {
+ if(errors!=0) {
+ System.err.println("Failed tests: " + errors +
+ "\nfailed test cases:\n");
+ for(String t: failedTests)
+ System.err.println(" " + t);
+ throw new RuntimeException("FAIL: There were test failures.");
+ } else
+ System.out.println("PASS");
+ }
+
+ void test(String clazz, String ttype, ClassFile cf, Method m, Field f,
+ String name, boolean codeattr) {
+ int actual = 0;
+ int expected = 0, cexpected = 0;
+ int index = 0;
+ String memberName = null;
+ Attribute attr = null;
+ Code_attribute cAttr = null;
+ String testcase = "undefined";
+ try {
+ switch(ttype) {
+ case "METHOD":
+ index = m.attributes.getIndex(cf.constant_pool, name);
+ memberName = m.getName(cf.constant_pool);
+ if(index != -1)
+ attr = m.attributes.get(index);
+ break;
+ case "MCODE":
+ memberName = m.getName(cf.constant_pool);
+ //fetch index of and code attribute and annotations from code attribute.
+ index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = m.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if(index!= -1)
+ attr = cAttr.attributes.get(index);
+ }
+ break;
+ case "FIELD":
+ index = f.attributes.getIndex(cf.constant_pool, name);
+ memberName = f.getName(cf.constant_pool);
+ if(index != -1)
+ attr = f.attributes.get(index);
+ break;
+ case "CODE":
+ memberName = f.getName(cf.constant_pool);
+ //fetch index of and code attribute and annotations from code attribute.
+ index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = cf.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if(index!= -1)
+ attr = cAttr.attributes.get(index);
+ }
+ break;
+ default:
+ break;
+ }
+ } catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
+ testcase = clazz+" "+ttype + ": " + memberName + ", " + name;
+ if(index != -1) {
+ //count RuntimeTypeAnnotations
+ assert attr instanceof RuntimeTypeAnnotations_attribute;
+ RuntimeTypeAnnotations_attribute tAttr =
+ (RuntimeTypeAnnotations_attribute)attr;
+ actual += tAttr.annotations.length;
+ }
+ if(memberName.compareTo("<init>")==0) memberName=clazz+memberName;
+ switch ( memberName ) {
+ //METHOD:
+ case "Test1<init>": expected=0; break;
+ case "testr22_22": expected=4; break;
+ case "testr11_11": expected=4; break;
+ case "testr12_21": expected=4; break;
+ case "testr20_02": expected=2; break;
+
+ case "Test2a<init>": cexpected=0; break;
+ case "test00_00_11_11": cexpected=4; break;
+ case "test21_12_21_12": cexpected=8; break;
+ case "test_new1": cexpected=2; break;
+ case "test_new2": cexpected=2; break;
+ case "test_cast1": cexpected=2; break;
+ case "test_cast2": cexpected=2; break;
+
+ case "Test2b<init>": cexpected=0; break;
+ case "test20_02_20_02": cexpected=4; break;
+ case "test22_22_22_22": cexpected=8; break;
+ case "test_new3": cexpected=1; break;
+ case "test_new4": cexpected=1; break;
+ case "test_new5": cexpected=2; break;
+ case "test_cast3": cexpected=1; break;
+ case "test_cast4": cexpected=2; break;
+
+ case "Test3a<init>": cexpected=10; break;
+ case "SA_21_12c": cexpected = 0; break;
+ case "SA_01_10c": expected = 0; break;
+ case "SA_11_11c": expected = 0; break;
+
+ case "Test3b<init>": cexpected=6; break;
+ case "SA_22_22c": cexpected = 0; break;
+ case "SA_20_02c": cexpected = 0; break;
+
+ case "Test3c<init>": cexpected=8; break;
+ case "SA_10_10": cexpected = 0; break;
+ case "SA_10_01": cexpected = 0; break;
+ case "SA_21_12": cexpected = 0; break;
+
+ case "Test3d<init>": cexpected=6; break;
+ case "SA_20_02": cexpected = 0; break;
+ case "SA_22_22": cexpected = 0; break;
+
+ case "Test4a<init>": cexpected=4; break;
+ case "nS_21": cexpected = 0; break;
+ case "nS_12": cexpected = 0; break;
+
+ case "Test4b<init>": cexpected=4; break;
+ case "nS20": cexpected = 0; break;
+ case "nS02": cexpected = 0; break;
+ case "nS22": cexpected = 0; break;
+
+ case "Test5a<init>": cexpected=4; break;
+ case "ci11": expected = 0; break;
+ case "ci21": expected = 0; break;
+
+ case "Test5b<init>": cexpected=3; break;
+ case "ci2": expected = 0; break;
+ case "ci22": expected = 0; break;
+
+ default: expected = 0; break;
+ }
+ if(codeattr)
+ check(testcase, cexpected, actual);
+ else
+ check(testcase, expected, actual);
+ }
+
+ public void run() {
+ ClassFile cf = null;
+ InputStream in = null;
+ for( String clazz : testclasses) {
+ String testclazz = "TestNewCastArray$" + clazz + ".class";
+ System.out.println("Testing " + testclazz);
+ try {
+ in = getClass().getResource(testclazz).openStream();
+ cf = ClassFile.read(in);
+ in.close();
+ } catch(Exception e) { e.printStackTrace(); }
+
+ if(clazz.startsWith("Test1")) {
+ for (Field f: cf.fields)
+ test(clazz, "FIELD", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, false);
+ for (Method m: cf.methods)
+ test(clazz, "METHOD", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, false);
+ } else {
+ for (Field f: cf.fields)
+ test(clazz, "CODE", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, true);
+ for (Method m: cf.methods)
+ test(clazz, "MCODE", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, true);
+ }
+ }
+ report();
+ }
+
+ //////// test class //////////////////////////
+ // "Test1" not in code attribute.
+ // on arrays on and in method return
+ static class Test1 {
+ Test1(){}
+ // OK expect 5, got 5
+ String @A @A @B @B[] @A @A @B @B [] testr22_22(Test1 this, String param, String ... vararg) {
+ String [][] sarray = new String [2][2];
+ return sarray;
+ }
+ // OK expect 5, got 5
+ String @A @B [] @A @B [] testr11_11(Test1 this, String param, String ... vararg) {
+ String [][] sarray = new String [2][2];
+ return sarray;
+ }
+ // OK expect 5, got 5
+ String @A @B @B []@B @B @A[] testr12_21(Test1 this, String param, String ... vararg) {
+ String [][] sarray = new String [2][2];
+ return sarray;
+ }
+ // OK expect 3, got 3
+ String @A @A [] @B @B [] testr20_02(Test1 this, String param, String ... vararg) {
+ String [][] sarray = new String [2][2];
+ return sarray;
+ }
+ }
+
+ // Inside method body (in method's code attribute)
+ static class Test2a {
+ Test2a(){}
+ Object o = new Integer(1);
+ // expect 4
+ String[][] test00_00_11_11(Test2a this, String param, String ... vararg) {
+ String [] [] sarray = new String @A @B[2] @A @B [2];
+ return sarray;
+ }
+
+ // expect 8
+ String[][] test21_12_21_12(Test2a this, String param, String ... vararg) {
+ String @A @A @B [] @A @B @B [] sarray = new String @A @A @B[2] @A @B @B [2];
+ return sarray;
+ }
+
+ void test_new1() { String nS_21 = new @A @A @B String("Hello"); }
+ void test_new2() { String nS_12 = new @A @B @B String("Hello"); }
+ void test_cast1() { String tcs11 = (@A @B String)o; }
+ void test_cast2() { String tcs21 = (@A @A @B String)o; }
+ }
+
+ static class Test2b {
+ Test2b(){}
+ Object o = new Integer(1);
+ // expect 4
+ String[][] test20_02_20_02(Test2b this, String param, String ... vararg) {
+ String @A @A [] @B @B [] sarray = new String @A @A[2] @B @B [2];
+ return sarray;
+ }
+
+ // expect 8
+ String[][] test22_22_22_22(Test2b this, String param, String ... vararg) {
+ String @A @A @B @B [] @A @A @B @B [] sarray = new String @A @A @B @B [2] @A @A @B @B [2];
+ return sarray;
+ }
+
+ void test_new3() { String nS20 = new @A @A String("Hello"); }
+ void test_new4() { String nS02 = new @B @B String("Hello"); }
+ void test_new5() { String nS22 = new @A @A @B @B String("Hello"); }
+ void test_cast3() { String tcs2 = (@A @A String)o; }
+ void test_cast4() { String tcs22 = (@A @A @B @B String)o;}
+ }
+
+ // array levels
+ static class Test3a {
+ Test3a(){}
+ // expect 4+2+4=10
+ String [][] SA_21_12c = new String @A @A @B [2] @A @B @B[2];
+ String [][] SA_01_10c = new String @B [2] @A [2];
+ String [][] SA_11_11c = new String @A @B [2] @A @B [2];
+ }
+
+ static class Test3b {
+ Test3b(){}
+ // expect 4+2=6
+ String [][] SA_22_22c = new String @A @A @B @B[2] @A @A @B @B[2];
+ String [][] SA_20_02c = new String @A @A [2] @B @B[2];
+ }
+ static class Test3c {
+ Test3c(){}
+ // OK expect 4
+ String @A [] @A[] SA_10_10 = new String [2][2];
+ String @A [] @B[] SA_10_01 = new String [2][2];
+ String @A @A @B[] @A @B @B [] SA_21_12 = new String [2][2];
+ }
+
+ static class Test3d {
+ Test3d(){}
+ // OK expect 4
+ String @A @A [] @B @B [] SA_20_02 = new String [2][2];
+ String @A @A @B @B[] @A @A @B @B [] SA_22_22 = new String [2][2];
+ }
+
+ // on new
+ static class Test4a {
+ Test4a(){}
+ // expect 2+2=4
+ String nS_21 = new @A @A @B String("Hello");
+ String nS_12 = new @A @B @B String("Hello");
+ }
+
+ static class Test4b {
+ Test4b(){}
+ // expect 1+1+2=4
+ String nS20 = new @A @A String("Hello");
+ String nS02 = new @B @B String("Hello");
+ String nS22 = new @A @A @B @B String("Hello");
+ }
+
+ // Cast expressions
+ static class Test5a {
+ Test5a(){}
+ Object o = new Integer(1);
+ // expect 2+2=4
+ Integer ci11 = (@A @B Integer)o; // OK expect 3, got 3
+ Integer ci21 = (@A @A @B Integer)o; // OK expect 3, got 3
+ }
+
+ static class Test5b {
+ Test5b(){}
+ Object o = new Integer(1);
+ // Cast expressions
+ // expect 1+2=3
+ Integer ci2 = (@A @A Integer)o; // FAIL expect 2, got 1
+ Integer ci22 = (@A @A @B @B Integer)o; // FAIL expect 3, got 1
+ }
+
+@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( AC.class ) @interface A { }
+@Retention(RUNTIME) @Target({TYPE_USE}) @Repeatable( BC.class ) @interface B { }
+@Retention(RUNTIME) @Target({FIELD}) @Repeatable( FC.class ) @interface F { }
+@Retention(RUNTIME) @Target({TYPE_USE}) @interface AC { A[] value(); }
+@Retention(RUNTIME) @Target({TYPE_USE}) @interface BC { B[] value(); }
+@Retention(RUNTIME) @Target({FIELD}) @interface FC { F[] value(); }
+
+}
+
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -50,7 +50,7 @@
test(cf, f);
}
for (Method m: cf.methods) {
- test(cf, m);
+ test(cf, m, true);
}
countAnnotations();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -48,7 +48,7 @@
test(cf, f);
}
for (Method m: cf.methods) {
- test(cf, m);
+ test(cf, m,false);
}
countAnnotations();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java Tue May 14 15:04:06 2013 -0700
@@ -27,7 +27,7 @@
* @summary Type annotations in a lazy constant need to be attributed
* in the correct order.
* @author Werner Dietl
- * @compile LazyConstantValue.java
+ * @compile/ref=LazyConstantValue.out LazyConstantValue.java
*/
import java.lang.annotation.*;
@@ -40,5 +40,9 @@
static final String[] lcv = new @TA String[0];
}
+class ClassC {
+ static final Object o = (@TA Object) null;
+}
+
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@interface TA {}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out Tue May 14 15:04:06 2013 -0700
@@ -1,11 +1,11 @@
LintCast.java:15:21: compiler.warn.redundant.cast: java.lang.String
LintCast.java:21:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
-LintCast.java:27:20: compiler.warn.redundant.cast: (@A :: int[])
+LintCast.java:27:20: compiler.warn.redundant.cast: int @A []
LintCast.java:39:24: compiler.warn.redundant.cast: java.lang.String
LintCast.java:40:26: compiler.warn.redundant.cast: java.lang.String
-LintCast.java:45:23: compiler.warn.redundant.cast: (@A :: java.lang.Object[])
+LintCast.java:45:23: compiler.warn.redundant.cast: java.lang.Object @A []
LintCast.java:49:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
-LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
+LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<@A java.lang.String>
LintCast.java:57:21: compiler.warn.redundant.cast: java.lang.Object
LintCast.java:61:27: compiler.warn.redundant.cast: LintCast.Outer.Inner
10 warnings
\ No newline at end of file
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java Tue May 14 15:04:06 2013 -0700
@@ -6,7 +6,7 @@
* @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java
*/
class StaticMethods {
- static void main(@A StaticMethods this) { }
+ static void main(StaticMethods this) { }
}
@interface A { }
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out Tue May 14 15:04:06 2013 -0700
@@ -1,2 +1,2 @@
-StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable
+StaticMethods.java:9:34: compiler.err.non-static.cant.be.ref: kindname.variable, this
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8008751.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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 type-annotation on array level in nested class results in NPE
+ * @bug 8008751
+ * @compile T8008751.java
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+import java.util.List;
+
+class T8008751 {
+ Object mtest( T8008751 t){ return null; }
+ public void test() {
+ mtest( new T8008751() {
+ class InnerAnon {
+ @A("ok") String s = (@A("ok") String)( new @A("ok") Object());
+ @A("ok") Object @A("NPE")[] [] ia_sa1 = null;
+ }
+ // If not instanciated, no crash.
+ InnerAnon IA = new InnerAnon();
+ });
+ }
+}
+@Retention(RUNTIME) @Target(TYPE_USE) @interface A { String value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8009360.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8009360
+ * @summary AssertionError from type annotation on member of anonymous class
+ * @compile T8009360.java
+ */
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+class Test1<T> {
+ Object mtest( Test1<T> t){ return null; }
+ public void test() {
+ mtest( new Test1<T>() {
+ @A String data1 = "test"; // ok
+ @A @A String data2 = "test"; // ok
+ @A @B String data3 = "test"; // was AssertionError
+ @B @C String data4 = "test"; // was AssertionError
+ });
+ }
+}
+
+@Target({TYPE_USE,FIELD}) @Repeatable( AC.class) @interface A { }
+@Target({TYPE_USE,FIELD}) @interface AC { A[] value(); }
+@Target({TYPE_USE}) @interface B { }
+@Target({TYPE_USE, FIELD}) @interface C { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8011722.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8011722
+ * @summary AssertionError from type annotations on qualified type
+ * @compile T8011722.java
+ */
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+public class T8011722 {
+ class InnerException extends Exception { }
+ void foo() throws @C T8011722.@C InnerException { }
+}
+
+@Target(ElementType.TYPE_USE) @interface C { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ * new array expressions
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+class DeclarationAnnotation {
+ Object e1 = new @DA int[5];
+ Object e2 = new @DA String[42];
+ Object e3 = new @DA Object();
+
+ // The declaration annotation is only allowed for
+ // an anonymous class creation.
+ Object ok = new @DA Object() { };
+}
+
+@interface DA { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,4 @@
+DeclarationAnnotation.java:10:21: compiler.err.annotation.type.not.applicable
+DeclarationAnnotation.java:11:21: compiler.err.annotation.type.not.applicable
+DeclarationAnnotation.java:12:21: compiler.err.annotation.type.not.applicable
+3 errors
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ * method receiver types
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+class DeclarationAnnotation {
+ void bad(@DA DeclarationAnnotation this) {}
+ void good(@TA DeclarationAnnotation this) {}
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.out Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:14:14: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java Tue May 14 15:04:06 2013 -0700
@@ -28,6 +28,11 @@
* @author Werner Dietl
* @compile Nesting.java
*/
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
@interface A { }
class Nesting {
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
-StaticThings.java:52:32: compiler.err.annotation.type.not.applicable
-StaticThings.java:54:37: compiler.err.annotation.type.not.applicable
-StaticThings.java:33:26: compiler.err.annotation.type.not.applicable
-StaticThings.java:36:28: compiler.err.annotation.type.not.applicable
-4 errors
\ No newline at end of file
+StaticThings.java:33:26: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:36:28: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:52:32: compiler.err.non-static.cant.be.ref: kindname.variable, this
+StaticThings.java:54:37: compiler.err.non-static.cant.be.ref: kindname.variable, this
+4 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java Tue May 14 15:04:06 2013 -0700
@@ -29,6 +29,10 @@
* @compile/fail/ref=WrongType.out -XDrawDiagnostics WrongType.java
*/
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
@interface A {}
class WrongType {
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out Tue May 14 15:04:06 2013 -0700
@@ -1,9 +1,9 @@
-WrongType.java:51:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:61:27: compiler.err.doesnt.exist: Outer
-WrongType.java:62:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:44:23: compiler.err.incorrect.receiver.type
-WrongType.java:46:23: compiler.err.incorrect.receiver.type
-WrongType.java:59:33: compiler.err.incorrect.receiver.type
-WrongType.java:60:31: compiler.err.incorrect.receiver.type
-WrongType.java:66:28: compiler.err.incorrect.receiver.type
-8 errors
\ No newline at end of file
+WrongType.java:48:16: compiler.err.incorrect.receiver.type: WrongType, java.lang.Object
+WrongType.java:50:16: compiler.err.incorrect.receiver.type: WrongType, java.lang.Object
+WrongType.java:55:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:63:23: compiler.err.incorrect.receiver.type: WrongType.Inner, WrongType
+WrongType.java:64:24: compiler.err.incorrect.receiver.type: WrongType.Inner, java.lang.Object
+WrongType.java:65:27: compiler.err.doesnt.exist: Outer
+WrongType.java:66:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:70:24: compiler.err.incorrect.receiver.type: WrongType.Generics<X>, WrongType.Generics<Y>
+8 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java Tue May 14 15:04:06 2013 -0700
@@ -5,10 +5,15 @@
* @author Mahmood Ali
* @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java
*/
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
class MissingAnnotationValue {
void test() {
new @A String();
}
}
+@Target(ElementType.TYPE_USE)
@interface A { int field(); }
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out Tue May 14 15:04:06 2013 -0700
@@ -1,2 +1,2 @@
-MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field
+MissingAnnotationValue.java:14:9: compiler.err.annotation.missing.default.value: A, field
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ * wildcards
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.List;
+
+class DeclarationAnnotation {
+ List<@DA ? extends Object> bad;
+ List<@TA ? extends Object> good;
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.out Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:15:10: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.lang.annotation.*;
+
+/*
+ * @test
+ * @bug 1234567
+ * @summary new type annotation location: anonymous class creation
+ * @author Werner Dietl
+ * @compile AnonymousClass.java
+ */
+class AnonymousClass {
+ Object o1 = new @TA Object() { };
+ // Declaration annotations are also allowed.
+ Object o2 = new @TA @DA Object() { };
+}
+
+@interface DA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java Tue May 14 15:04:06 2013 -0700
@@ -50,6 +50,13 @@
return LambdaImpl::<@TA Object, @TB Object>new;
}
+ interface LambdaInt2 {
+ void lambda(Object p1, Object p2);
+ }
+
+ LambdaInt2 getLambda() {
+ return (@TA Object x, @TB Object y) -> { @TA Object l = null; System.out.println("We have: " + (@TB Object) x); };
+ }
}
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java Tue May 14 15:04:06 2013 -0700
@@ -25,7 +25,6 @@
/*
* @test
- * @ignore 8013408: Need specification for type exceptions on multicatch
* @bug 8006775
* @summary new type annotation location: multicatch
* @author Werner Dietl
@@ -40,6 +39,8 @@
e.toString();
}
}
+ /* Disabled: there is no syntax to annotate all components
+ * of the multicatch.
void exception02() {
try {
System.out.println("Hello 2!");
@@ -47,18 +48,24 @@
e.toString();
}
}
+ */
}
class ModifiedVars {
- /*
- void exception() {
+ void exception01() {
try {
- arrays();
- } catch (final @A Exception e) {
+ System.out.println("Hello 1!");
+ } catch (final @B NullPointerException | @C IllegalArgumentException e) {
e.toString();
}
}
- */
+ void exception02() {
+ try {
+ System.out.println("Hello 1!");
+ } catch (@Decl @B NullPointerException | @C IllegalArgumentException e) {
+ e.toString();
+ }
+ }
}
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@@ -67,5 +74,5 @@
@interface B { }
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@interface C { }
-@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@interface D { }
+
+@interface Decl { }
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -54,7 +54,6 @@
" } }";
}
- /* TODO: Outer.this annotation support.
@TADescriptions({
@TADescription(annotation = "TA", type = METHOD_RECEIVER),
@TADescription(annotation = "TB", type = METHOD_RETURN),
@@ -69,5 +68,21 @@
" @TD Inner(@TC Test Test.this, @TE int b) {}" +
" } }";
}
- */
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = METHOD_RECEIVER),
+ @TADescription(annotation = "TB", type = METHOD_RECEIVER, genericLocation = {1, 0}),
+ @TADescription(annotation = "TC", type = METHOD_RETURN),
+ @TADescription(annotation = "TD", type = METHOD_RECEIVER, genericLocation = {1, 0}),
+ @TADescription(annotation = "TE", type = METHOD_RETURN),
+ @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0)
+ })
+ @TestClass("Outer$Middle$Inner")
+ public String innerClass3() {
+ return "class Outer { class Middle { class Inner {" +
+ " @TC Inner(@TA Outer. @TB Middle Middle.this) {}" +
+ " @TE Inner(@TD Middle Outer.Middle.this, @TF int b) {}" +
+ " } } }";
+ }
+
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java Tue May 14 15:04:06 2013 -0700
@@ -207,7 +207,7 @@
if (isSnippet) {
// Have a few common nested types for testing
- sb.append("class Outer { class Inner {} }");
+ sb.append("class Outer { class Inner {} class Middle { class MInner {} } }");
sb.append("class SOuter { static class SInner {} }");
sb.append("class GOuter<X, Y> { class GInner<X, Y> {} }");
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java Tue May 14 15:04:06 2013 -0700
@@ -47,11 +47,43 @@
@TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
@TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
})
- public String multipleExceptions() {
+ public String multipleExceptions1() {
return "void multipleExceptions() { " +
"try { new Object(); } catch(@TA Exception e) { }" +
"try { new Object(); } catch(@TB Exception e) { }" +
"try { new Object(); } catch(@TC Exception e) { }" +
" }";
}
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+ @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+ @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+ })
+ public String multipleExceptions2() {
+ return "void multipleExceptions() { " +
+ " try { new Object(); " +
+ " try { new Object(); " +
+ " try { new Object(); } catch(@TA Exception e) { }" +
+ " } catch(@TB Exception e) { }" +
+ " } catch(@TC Exception e) { }" +
+ "}";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0),
+ @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+ @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2)
+ })
+ public String multipleExceptions3() {
+ return "void multipleExceptions() { " +
+ " try { new Object(); " +
+ " } catch(@TA Exception e1) { "+
+ " try { new Object(); " +
+ " } catch(@TB Exception e2) {" +
+ " try { new Object(); } catch(@TC Exception e3) { }" +
+ " }" +
+ " }" +
+ "}";
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
+
+/*
+ * @test
+ * @bug 1234567
+ * @summary Test population of reference info for instance and class initializers
+ * @author Werner Dietl
+ * @compile -g Driver.java ReferenceInfoUtil.java Initializers.java
+ * @run main Driver Initializers
+ */
+public class Initializers {
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TB", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+ })
+ public String instanceInit1() {
+ return "class Test { { Object o = new @TA ArrayList<@TB String>(); } }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TB", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TD", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+ })
+ public String instanceInit2() {
+ return "class Test { Object f = new @TA ArrayList<@TB String>(); " +
+ " { Object o = new @TC ArrayList<@TD String>(); } }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TB", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+ })
+ public String staticInit1() {
+ return "class Test { static { Object o = new @TA ArrayList<@TB String>(); } }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TB", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TD", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TF", type = NEW,
+ genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+ })
+ public String staticInit2() {
+ return "class Test { Object f = new @TA ArrayList<@TB String>(); " +
+ " static Object g = new @TC ArrayList<@TD String>(); " +
+ " static { Object o = new @TE ArrayList<@TF String>(); } }";
+ }
+
+ // TODO: test interaction with several constructors, especially non-initial constuctors.
+ // I don't think this kind of test is possible here.
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = CAST,
+ typeIndex = 0, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ })
+ public String lazyConstantCast1() {
+ return "class Test { public static final Object o = (@TA Object) null; }";
+ }
+
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java Tue May 14 15:04:06 2013 -0700
@@ -259,4 +259,30 @@
"}";
}
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+ paramIndex = 0),
+ @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+ paramIndex = 1),
+ @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
+ paramIndex = 1, genericLocation = { 3, 0 }),
+ @TADescription(annotation = "TD", type = LOCAL_VARIABLE,
+ lvarOffset = ReferenceInfoUtil.IGNORE_VALUE,
+ lvarLength = ReferenceInfoUtil.IGNORE_VALUE,
+ lvarIndex = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TE", type = CAST,
+ offset = ReferenceInfoUtil.IGNORE_VALUE,
+ typeIndex = 0)
+ })
+ public String returnLambdaExpr1() {
+ return
+ "interface LambdaInt {" +
+ " void lambda(Object p1, List<Object> p2);" +
+ "}" +
+ "class Test {" +
+ " LambdaInt getLambda() {" +
+ " return (@TA Object x, @TB List<@TC Object> y) -> { @TD Object l = null; System.out.println((@TE Object) l); };" +
+ " }" +
+ "}";
+ }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -54,4 +54,24 @@
public String interfaceMethod() {
return "interface Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }";
}
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = THROWS, typeIndex = 0,
+ genericLocation = {}),
+ @TADescription(annotation = "TB", type = THROWS, typeIndex = 0,
+ genericLocation = {1, 0}),
+ @TADescription(annotation = "TC", type = THROWS, typeIndex = 0,
+ genericLocation = {1, 0, 1, 0}),
+ @TADescription(annotation = "TD", type = THROWS, typeIndex = 1,
+ genericLocation = {}),
+ @TADescription(annotation = "TE", type = THROWS, typeIndex = 1,
+ genericLocation = {1, 0}),
+ @TADescription(annotation = "TF", type = THROWS, typeIndex = 1,
+ genericLocation = {1, 0, 1, 0})
+ })
+ public String NestedTypes() {
+ return "class Outer { class Middle { class Inner1 extends Exception {}" +
+ " class Inner2 extends Exception{} } }" +
+ "class Test { void test() throws @TA Outer.@TB Middle.@TC Inner1, @TD Outer.@TE Middle.@TF Inner2 { } }";
+ }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java Tue May 14 15:04:06 2013 -0700
@@ -26,7 +26,6 @@
/*
* @test
* @bug 8006732 8006775
- * @ignore 8013408: Need specification for type exceptions on multicatch
* @summary Test population of reference info for multicatch exception parameters
* @author Werner Dietl
* @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java
@@ -53,4 +52,16 @@
"try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException | @TC IllegalArgumentException e) { e.toString(); } }";
}
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+ @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1),
+ @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+ @TADescription(annotation = "TD", type = EXCEPTION_PARAMETER, exceptionIndex = 2),
+ @TADescription(annotation = "TE", type = EXCEPTION_PARAMETER, exceptionIndex = 3),
+ })
+ public String multiCatch3() {
+ return "void multiCatch3() { " +
+ "try { new Object(); } catch (NullPointerException e1) {}" +
+ "try { new Object(); } catch (@TA @TB NullPointerException | @TC @TD IndexOutOfBoundsException | @TE IllegalArgumentException e2) { e2.toString(); } }";
+ }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -831,4 +831,48 @@
" }\n" +
"}}\n";
}
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = CLASS_EXTENDS,
+ genericLocation = {}, typeIndex = -1),
+ @TADescription(annotation = "TB", type = CLASS_EXTENDS,
+ genericLocation = {3, 0}, typeIndex = -1),
+ @TADescription(annotation = "TC", type = CLASS_EXTENDS,
+ genericLocation = {3, 1}, typeIndex = -1),
+ @TADescription(annotation = "TD", type = CLASS_EXTENDS,
+ genericLocation = {1, 0}, typeIndex = -1),
+ @TADescription(annotation = "TE", type = CLASS_EXTENDS,
+ genericLocation = {1, 0, 3, 0}, typeIndex = -1),
+ @TADescription(annotation = "TF", type = CLASS_EXTENDS,
+ genericLocation = {1, 0, 3, 1}, typeIndex = -1)
+ })
+ @TestClass("GOuter$GInner$Test")
+ public String testExtends1() {
+ return "class GOuter<A, B> {\n" +
+ " class GInner<X, Y> {\n" +
+ " class Test extends @TA GOuter<@TB String, @TC String>.@TD GInner<@TE String, @TF String> {}" +
+ " }" +
+ "}";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER,
+ genericLocation = {}, paramIndex = 0),
+ @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND,
+ genericLocation = {}, paramIndex = 0, boundIndex = 0),
+ @TADescription(annotation = "TC", type = FIELD,
+ genericLocation = {}),
+ @TADescription(annotation = "TD", type = FIELD,
+ genericLocation = {3, 0})
+ })
+ @TestClass("Test$1Nested")
+ public String testNestedInMethod1() {
+ return "class Test {\n" +
+ " void foobar() {\n" +
+ " class Nested<@TA X extends @TB Object> {\n" +
+ " @TC List<@TD Object> f;\n" +
+ " }\n" +
+ " }" +
+ "}";
+ }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -75,4 +75,81 @@
return "void eqtestObjectGeneric() { if (null == new @TA ArrayList<@TB String >()); }";
}
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0}),
+ @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE)
+ })
+ public String returnNewArray1() {
+ return "Object returnNewArray1() { return new @TA String @TB[1]; }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0}),
+ @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0}),
+ })
+ public String returnNewArray2() {
+ return "Object returnNewArray2() { return new @TA String @TB [1] @TC [2]; }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0}),
+ @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0, 1, 0}),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0}),
+ })
+ public String returnNewArray3() {
+ return "Object returnNewArray3() { return new @TA Outer. @TB Inner @TC [1] @TD [2]; }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0}),
+ @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0, 1, 0}),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}),
+ @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0}),
+ })
+ public String returnNewArray4() {
+ return "Object returnNewArray4() { return new @TA Outer. @TB Middle. @TC MInner @TD [1] @TE [2]; }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TB", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {3, 0, 0, 0, 0, 0}),
+ @TADescription(annotation = "TC", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}),
+ @TADescription(annotation = "TD", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}),
+ @TADescription(annotation = "TE", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {3, 0}),
+ @TADescription(annotation = "TF", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {3, 0, 0, 0}),
+ })
+ public String returnNewArray5() {
+ return "Object returnNewArray5() { return new @TA ArrayList<@TB Outer. @TC Middle. @TD MInner @TE [] @TF []>(); }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0}),
+ @TADescription(annotation = "TB", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0, 0, 0, 1, 0}),
+ @TADescription(annotation = "TC", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE),
+ @TADescription(annotation = "TD", type = FIELD, offset = ReferenceInfoUtil.IGNORE_VALUE,
+ genericLocation = {0, 0}),
+ })
+ public String arrayField() {
+ return "@TA Outer. @TB Inner @TC [] @TD [] f;";
+ }
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -28,6 +28,7 @@
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
@@ -90,6 +91,20 @@
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
}
+
+ int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if (cindex != -1) {
+ Attribute cattr = m.attributes.get(cindex);
+ assert cattr instanceof Code_attribute;
+ Code_attribute cAttr = (Code_attribute)cattr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if (index != -1) {
+ Attribute attr = cAttr.attributes.get(index);
+ assert attr instanceof RuntimeTypeAnnotations_attribute;
+ RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+ annos.addAll(Arrays.asList(tAttr.annotations));
+ }
+ }
}
// test the result of Attributes.getIndex according to expectations
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,33 @@
+
+import java.util.*;
+import java.lang.annotation.*;
+
+class Test<K> { GOuter<@TC Object, String> entrySet() { return null; } }
+
+@interface A {}
+@interface B {}
+@interface C {}
+@interface D {}
+@interface E {}
+@interface F {}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TB {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TC {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TD {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TE {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TF {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TG {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TH {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TI {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TJ {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TK {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TL {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TM {}
+
+@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}
+@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}
+@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }
+@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }
+@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
+@interface Decl {}
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java Tue May 14 15:04:06 2013 -0700
@@ -111,7 +111,8 @@
DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz);
for (Element member : elements.getAllMembers((TypeElement)type.asElement())) {
TypeMirror mt = types.asMemberOf(type, member);
- System.out.format("%s : %s -> %s%n", member.getSimpleName(), member.asType(), mt);
+ System.out.format("type#%d: %s : %s -> %s%n",
+ numParseTypeElements, member.getSimpleName(), member.asType(), mt);
numParseTypeElements++;
}
}
@@ -123,7 +124,8 @@
private void testGetAllMembers(TypeElement clazz) {
for (Element member : elements.getAllMembers(clazz)) {
- System.out.format("%s : %s%n", member.getSimpleName(), member.asType());
+ System.out.format("elem#%d: %s : %s%n",
+ numAllMembers, member.getSimpleName(), member.asType());
numAllMembers++;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, 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.array.and.receiver
+// key: compiler.err.expected
+// key: compiler.err.expected3
+// key: compiler.err.illegal.start.of.type
+
+class ArrayAndReceiver {
+ void m(ArrayAndReceiver this[]) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverName.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 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.incorrect.constructor.receiver.name
+
+class IncorrectConstructorReceiverName {
+ class Inner {
+ Inner(IncorrectConstructorReceiverName this) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncorrectConstructorReceiverType.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 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.incorrect.constructor.receiver.type
+
+class IncorrectConstructorReceiverType {
+ class Inner {
+ Inner(Object IncorrectConstructorReceiverType.this) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncorrectReceiverName.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2013, 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.incorrect.receiver.name
+
+class IncorrectReceiverName {
+ class Inner {
+ void m(Inner IncorrectReceiverName.this) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ReceiverParameterNotApplicableConstructor.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, 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.receiver.parameter.not.applicable.constructor.toplevel.class
+
+class ReceiverParameterNotApplicableConstructor {
+ ReceiverParameterNotApplicableConstructor(ReceiverParameterNotApplicableConstructor this) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/VarargsAndReceiver.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, 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.varargs.and.receiver
+
+class VarargsAndReceiver {
+ void m(VarargsAndReceiver... this) { }
+}
--- a/langtools/test/tools/javac/lib/DPrinter.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/lib/DPrinter.java Tue May 14 15:04:06 2013 -0700
@@ -469,6 +469,7 @@
indent(+1);
printSymbol("tsym", type.tsym, Details.SUMMARY);
printObject("constValue", type.constValue(), Details.SUMMARY);
+ printObject("annotations", type.getAnnotationMirrors(), Details.SUMMARY);
type.accept(typeVisitor, null);
indent(-1);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java Tue May 14 15:04:06 2013 -0700
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 1234567
+ * @summary Annotations on types
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests
+ * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java
+ */
+
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.tools.Diagnostic.Kind;
+
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+
+/**
+ * The test scans this file looking for test cases annotated with @Test.
+ */
+public class BasicAnnoTests extends JavacTestingAbstractProcessor {
+ DPrinter dprinter;
+ PrintWriter out;
+ boolean verbose = true;
+
+ @Override
+ public void init(ProcessingEnvironment pEnv) {
+ super.init(pEnv);
+ dprinter = new DPrinter(((JavacProcessingEnvironment) pEnv).getContext());
+ out = dprinter.out;
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ TestElementScanner s = new TestElementScanner();
+ for (Element e: roundEnv.getRootElements()) {
+ s.scan(e);
+ }
+ return true;
+ }
+
+ void error(Element e, String msg) {
+ messager.printMessage(Kind.ERROR, msg, e);
+ errors++;
+ }
+
+ int errors;
+
+ /**
+ * Scan an element looking for declarations annotated with @Test.
+ * Run a TestTypeScanner on the annotations that are found.
+ */
+ class TestElementScanner extends ElementScanner<Void,Void> {
+ public Void scan(Element elem, Void ignore) {
+ AnnotationMirror test = getAnnotation(elem, Test.class.getName().replace('$', '.'));
+ if (test != null) {
+ out.println("Test: " + elem + " " + test);
+ TestTypeScanner s = new TestTypeScanner(elem, test);
+ s.scan(elem.asType(), null);
+ if (getPosn(test) >= s.count)
+ error(elem, "position " + getPosn(test) + " not found");
+ if (!s.found) {
+ dprinter.printSymbol("element", (Symbol) elem);
+ dprinter.printType("type", (Type) elem.asType());
+ }
+ out.println();
+ }
+ return super.scan(elem, ignore);
+ }
+ }
+
+ /**
+ * Scan the type of an element, looking for an annotation
+ * to match the expected annotation specified in the @Test annotation.
+ */
+ class TestTypeScanner extends TypeScanner<Void, Void> {
+ Element elem;
+ AnnotationMirror test;
+ int count = 0;
+ boolean found = false;
+
+ TestTypeScanner(Element elem, AnnotationMirror test) {
+ this.elem = elem;
+ this.test = test;
+ }
+
+ @Override
+ Void scan(TypeMirror t, Void ignore) {
+ if (t == null)
+ return DEFAULT_VALUE;
+ if (verbose)
+ out.println("scan " + count + ": " + t);
+ if (count == getPosn(test)) {
+ String annoType = getAnnoType(test);
+ AnnotationMirror anno = getAnnotation(t, annoType);
+ if (anno == null) {
+ error(elem, "annotation not found on " + count + ": " + t);
+ } else {
+ String v = getValue(anno, "value").toString();
+ if (v.equals(getExpect(test))) {
+ out.println("found " + anno + " as expected");
+ found = true;
+ } else {
+ error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test));
+ }
+ }
+ }
+ count++;
+ return super.scan(t, ignore);
+ }
+ }
+
+ /** Get the position value from an @Test annotation mirror. */
+ static int getPosn(AnnotationMirror test) {
+ AnnotationValue v = getValue(test, "posn");
+ return (Integer) v.getValue();
+ }
+
+ /** Get the expect value from an @Test annotation mirror. */
+ static String getExpect(AnnotationMirror test) {
+ AnnotationValue v = getValue(test, "expect");
+ return (String) v.getValue();
+ }
+
+ /** Get the annoType value from an @Test annotation mirror. */
+ static String getAnnoType(AnnotationMirror test) {
+ AnnotationValue v = getValue(test, "annoType");
+ TypeMirror m = (TypeMirror) v.getValue();
+ return m.toString();
+ }
+
+ /**
+ * Get a specific annotation mirror from an annotated construct.
+ */
+ static AnnotationMirror getAnnotation(AnnotatedConstruct e, String name) {
+ for (AnnotationMirror m: e.getAnnotationMirrors()) {
+ TypeElement te = (TypeElement) m.getAnnotationType().asElement();
+ if (te.getQualifiedName().contentEquals(name)) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get a specific value from an annotation mirror.
+ */
+ static AnnotationValue getValue(AnnotationMirror anno, String name) {
+ Map<? extends ExecutableElement, ? extends AnnotationValue> map = anno.getElementValues();
+ for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e: map.entrySet()) {
+ if (e.getKey().getSimpleName().contentEquals(name)) {
+ return e.getValue();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * The Language Model API does not provide a type scanner, so provide
+ * one sufficient for our needs.
+ */
+ static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> {
+ @Override
+ public R visitArray(ArrayType t, P p) {
+ scan(t.getComponentType(), p);
+ return super.visitArray(t, p);
+ }
+
+ @Override
+ public R visitExecutable(ExecutableType t, P p) {
+ scan(t.getReceiverType());
+ //out.println(" params: " + t.getParameterTypes());
+ scan(t.getParameterTypes(), p);
+ //out.println(" return: " + t.getReturnType());
+ scan(t.getReturnType(), p);
+ //out.println(" throws: " + t.getThrownTypes());
+ scan(t.getThrownTypes(), p);
+ return super.visitExecutable(t, p);
+ }
+
+ @Override
+ public R visitTypeVariable(TypeVariable t, P p) {
+ scan(t.getLowerBound(), p);
+ scan(t.getUpperBound(), p);
+ return super.visitTypeVariable(t, p);
+ }
+
+ @Override
+ public R visitWildcard(WildcardType t, P p) {
+ scan(t.getExtendsBound(), p);
+ scan(t.getSuperBound(), p);
+ return super.visitWildcard(t, p);
+ }
+
+ R scan(TypeMirror t) {
+ return scan(t, null);
+ }
+
+ R scan(TypeMirror t, P p) {
+ return (t == null) ? DEFAULT_VALUE : t.accept(this, p);
+ }
+
+ R scan(Iterable<? extends TypeMirror> iter, P p) {
+ if (iter == null)
+ return DEFAULT_VALUE;
+ R result = DEFAULT_VALUE;
+ for (TypeMirror t: iter)
+ result = scan(t, p);
+ return result;
+ }
+ }
+
+ /** Annotation to identify test cases. */
+ @interface Test {
+ /** Where to look for the annotation, expressed as a scan index. */
+ int posn();
+ /** The annotation to look for. */
+ Class<? extends Annotation> annoType();
+ /** The string representation of the annotation's value. */
+ String expect();
+ }
+
+ /** Type annotation to use in test cases. */
+ @Target(ElementType.TYPE_USE)
+ public @interface TA {
+ int value();
+ }
+
+ @Test(posn=0, annoType=TA.class, expect="1")
+ public @TA(1) int f1;
+
+ @Test(posn=0, annoType=TA.class, expect="2")
+ public int @TA(2) [] f2;
+
+ @Test(posn=1, annoType=TA.class, expect="3")
+ public @TA(3) int [] f3;
+
+ @Test(posn=1, annoType=TA.class, expect="4")
+ public int m1(@TA(4) float a) throws Exception { return 0; }
+
+ @Test(posn=2, annoType=TA.class, expect="5")
+ public @TA(5) int m2(float a) throws Exception { return 0; }
+
+ @Test(posn=3, annoType=TA.class, expect="6")
+ public int m3(float a) throws @TA(6) Exception { return 0; }
+}
--- a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java Tue May 14 15:04:06 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, 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
@@ -36,6 +36,7 @@
/*
* @test
* @bug 6923080
+ * @ignore 8014323: Add VariableTree.getNameExpression
* @summary TreeScanner.visitNewClass should scan tree.typeargs
* @build AbstractTreeScannerTest SourceTreeScannerTest
* @run main SourceTreeScannerTest -q -r .
--- a/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java Tue May 14 15:04:06 2013 -0700
@@ -121,280 +121,307 @@
*/
@TestCase
- @ignore // 8008082: missing type annotation for cast
public static class TC1 extends RepeatingTypeAnnotations {
public TC1() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC1 */ ",
+ " static String so = \"hello world\";",
" public @A @A @A Object o = (@A @A @A String) Test.so;");
verify("RuntimeInvisibleTypeAnnotations",
"0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
- "1: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5");
+ "0: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC2 extends RepeatingTypeAnnotations {
public TC2() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC2 */ ",
+ " static String so = \"hello world\";",
" public @A @B @A Object o = (@B @A @B String) Test.so;");
verify("RuntimeInvisibleTypeAnnotations",
"0: #25(#26=[@#27(),@#27()]): FIELD",
"1: #28(): FIELD",
- "2: #29(#26=[@#28(),@#28()]): CAST, offset=5",
- "3: #27(): CAST, offset=5");
+ "0: #36(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
+ "1: #27(): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC3 extends RepeatingTypeAnnotations {
public TC3() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC3 */ ",
+ " static String so = \"hello world\";",
" public @A @A @C Object o = (@B @C @B String) Test.so;");
- verify("RuntimeInvisibleTypeAnnotations",
+ verify("RuntimeVisibleTypeAnnotations",
+ "RuntimeInvisibleTypeAnnotations",
"0: #25(): FIELD",
- "1: #25(): CAST, offset=5",
- "RuntimeVisibleTypeAnnotations",
"0: #27(#28=[@#29(),@#29()]): FIELD",
- "1: #30(#28=[@#31(),@#31()]): CAST, offset=5");
+ "0: #25(): CAST, offset=5, type_index=0",
+ "0: #37(#28=[@#38(),@#38()]): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC4 extends RepeatingTypeAnnotations {
public TC4() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC4 */ ",
+ " static String so = \"hello world\";",
" public @A @B @C Object o = (@C @B @A String) Test.so;");
verify("RuntimeInvisibleTypeAnnotations",
"RuntimeVisibleTypeAnnotations",
"0: #25(): FIELD",
- "1: #25(): CAST, offset=5",
"0: #27(): FIELD",
"1: #28(): FIELD",
- "2: #28(): CAST, offset=5",
- "3: #27(): CAST, offset=5");
+ "0: #25(): CAST, offset=5, type_index=0",
+ "0: #28(): CAST, offset=5, type_index=0",
+ "1: #27(): CAST, offset=5, type_index=0");
}
}
@TestCase
- @ignore // 8008082: missing type annotation for cast
public static class TC5 extends RepeatingTypeAnnotations {
public TC5() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC5 */ ",
+ " static String so = \"hello world\";",
" public static @A @A @A Object o = (@B @B @B String) Test.so;");
verify("RuntimeInvisibleTypeAnnotations",
"0: #25(#26=[@#27(),@#27(),@#27()]): FIELD",
- "1: #28(#26=[@#29(),@#29(),@#29()]): CAST, offset=5, type_index=0");
+ "0: #36(#26=[@#37(),@#37(),@#37()]): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC6 extends RepeatingTypeAnnotations {
public TC6() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC6 */ ",
+ " static String so = \"hello world\";",
" public static @A @B @A Object o = (@B @A @B String) Test.so;");
verify("RuntimeInvisibleTypeAnnotations",
"0: #25(#26=[@#27(),@#27()]): FIELD",
"1: #28(): FIELD",
- "2: #29(#26=[@#28(),@#28()]): CAST, offset=5",
- "3: #27(): CAST, offset=5");
+ "0: #37(#26=[@#28(),@#28()]): CAST, offset=5, type_index=0",
+ "1: #27(): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC7 extends RepeatingTypeAnnotations {
public TC7() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC7 */ ",
+ " static String so = \"hello world\";",
" public static @A @A @C Object o = (@B @C @B String) Test.so;");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
+ verify("RuntimeVisibleTypeAnnotations",
+ "RuntimeInvisibleTypeAnnotations",
"0: #25(): FIELD",
- "1: #25(): CAST, offset=5",
"0: #27(#28=[@#29(),@#29()]): FIELD",
- "1: #30(#28=[@#31(),@#31()]): CAST, offset=5");
+ "0: #25(): CAST, offset=5, type_index=0",
+ "0: #38(#28=[@#39(),@#39()]): CAST, offset=5, type_index=0");
}
}
@TestCase
public static class TC8 extends RepeatingTypeAnnotations {
public TC8() {
- setSrc(" static String so = \"hello world\";",
+ setSrc(" /* TC8 */ ",
+ " static String so = \"hello world\";",
" public static @A @B @C Object o = (@C @B @A String) Test.so;");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
+
+ verify("RuntimeVisibleTypeAnnotations",
+ "RuntimeInvisibleTypeAnnotations",
"0: #25(): FIELD",
- "1: #25(): CAST, offset=5",
"0: #27(): FIELD",
"1: #28(): FIELD",
- "2: #28(): CAST, offset=5",
- "3: #27(): CAST, offset=5");
+ "0: #25(): CAST, offset=5, type_index=0",
+ "0: #28(): CAST, offset=5, type_index=0",
+ "1: #27(): CAST, offset=5, type_index=0");
}
}
@TestCase
- @ignore // 8008082: missing type annotation for cast
public static class TC9 extends RepeatingTypeAnnotations {
public TC9() {
- setSrc(" public Test(@A @A @A Object o, @A int i, long l) {",
+ setSrc(" /* TC9 */ ",
+ " public Test(@A @A @A Object o, @A int i, long l) {",
" @A @A @A String ls = (@B @B @B String) o;",
" }");
verify("RuntimeInvisibleTypeAnnotations",
- "0: #34(#35=[@#36(),@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "1: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
- "2: #37(#35=[@#38(),@#38(),@#38()]): CAST, offset=4, type_index=0",
- "3: #34(#35=[@#36(),@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+ "0: #34(#35=[@#36(),@#36(),@#36()]): CAST, offset=4, type_index=0",
+ "1: #37(#35=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "RuntimeInvisibleTypeAnnotations",
+ "0: #37(#35=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "1: #38(): METHOD_FORMAL_PARAMETER, param_index=1");
}
}
@TestCase
public static class TC10 extends RepeatingTypeAnnotations {
public TC10() {
- setSrc(" public Test(@A @A @B Object o, @A @B int i, long l) {",
+ setSrc(" /* TC10 */ ",
+ " public Test(@A @A @B Object o, @A @B int i, long l) {",
" @A @A @B String ls = (@B @A @B String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations:",
- "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
- "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
- "4: #38(#35=[@#37(),@#37()]): CAST, offset=4, type_index=0",
- "5: #36(): CAST, offset=4, type_index=0",
- "6: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
- "7: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+ verify("RuntimeInvisibleTypeAnnotations",
+ "0: #34(#35=[@#36(),@#36()]): CAST, offset=4, type_index=0",
+ "1: #37(): CAST, offset=4, type_index=0",
+ "2: #38(#35=[@#37(),@#37()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "3: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "RuntimeInvisibleTypeAnnotations",
+ "0: #38(#35=[@#37(),@#37()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
+ "2: #37(): METHOD_FORMAL_PARAMETER, param_index=1",
+ "3: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
}
}
@TestCase
public static class TC11 extends RepeatingTypeAnnotations {
public TC11() {
- setSrc(" public Test(@C @C @A Object o, @A @B int i, long l) {",
+ setSrc(" /* TC11 */ ",
+ " public Test(@C @C @A Object o, @A @B int i, long l) {",
" @C @C @A String ls = (@A @A @C String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
- "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "1: #36(): CAST, offset=4",
- "2: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
- "0: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
- "1: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
- "2: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #40(#35=[@#38(),@#38()]): CAST, offset=4",
- "4: #38(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+ verify("RuntimeVisibleTypeAnnotations",
+ "RuntimeInvisibleTypeAnnotations",
+ "0: #34(): CAST, offset=4, type_index=0",
+ "1: #35(#36=[@#34(),@#34()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "0: #38(#36=[@#39(),@#39()]): CAST, offset=4, type_index=0",
+ "1: #39(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "0: #35(#36=[@#34(),@#34()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "0: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
+ "1: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
+ "2: #40(): METHOD_FORMAL_PARAMETER, param_index=1");
}
}
@TestCase
public static class TC12 extends RepeatingTypeAnnotations {
public TC12() {
- setSrc(" public Test(@A @B @C Object o, @A @C int i, long l) {",
+ setSrc(" /* TC12 */ ",
+ " public Test(@A @B @C Object o, @A @C int i, long l) {",
" @A @B @C String ls = (@C @A @B String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
+ verify("RuntimeVisibleTypeAnnotations",
+ "0: #34(): CAST, offset=4, type_index=0",
+ "1: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "RuntimeInvisibleTypeAnnotations",
+ "0: #36(): CAST, offset=4, type_index=0",
+ "1: #37(): CAST, offset=4, type_index=0",
+ "2: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
+ "3: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
"0: #34(): METHOD_FORMAL_PARAMETER, param_index=0",
"1: #34(): METHOD_FORMAL_PARAMETER, param_index=1",
- "2: #34(): CAST, offset=4",
- "3: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
"0: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
"1: #37(): METHOD_FORMAL_PARAMETER, param_index=0",
- "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #36(): CAST, offset=4",
- "4: #37(): CAST, offset=4",
- "5: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}",
- "6: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}");
+ "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1");
}
}
@TestCase
- @ignore // 8008082: missing type annotation for cast
public static class TC13 extends RepeatingTypeAnnotations {
public TC13() {
- setSrc(" public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
+ setSrc(" /* TC13 */ ",
+ " public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {",
" @A @A @A String ls = (@B @B @B String) o;",
" return (@A @A @A String) o;",
" }");
verify("RuntimeInvisibleTypeAnnotations",
- "0: #36(#37=[@#38(),@#38(),@#38()]): METHOD_RETURN",
- "1: #36(#37=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "2: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=0, type_index=0",
- "4: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=6, type_index=0",
- "5: #36(#37=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+ "0: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=0, type_index=0",
+ "1: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=6, type_index=0",
+ "2: #39(#37=[@#40(),@#40(),@#40()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeInvisibleTypeAnnotations",
+ "0: #39(#37=[@#40(),@#40(),@#40()]): METHOD_RETURN",
+ "1: #39(#37=[@#40(),@#40(),@#40()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "2: #40(): METHOD_FORMAL_PARAMETER, param_index=1");
}
}
@TestCase
public static class TC14 extends RepeatingTypeAnnotations {
public TC14() {
- setSrc(" public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
+ setSrc(" /* TC14 */ ",
+ " public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {",
" @A @A @B String ls = (@B @A @B String) o;",
" return (@A @B @B String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations",
- "0: #36(): METHOD_RETURN",
- "1: #37(#38=[@#39(),@#39()]): METHOD_RETURN",
- "2: #40(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
- "4: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
- "5: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
- "6: #37(#38=[@#39(),@#39()]): CAST, offset=0",
- "7: #36(): CAST, offset=0",
- "8: #36(): CAST, offset=6",
- "9: #37(#38=[@#39(),@#39()]): CAST, offset=6",
- "10: #40(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
- "11: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+ verify(
+ "RuntimeInvisibleTypeAnnotations:",
+ "0: #36(#37=[@#38(),@#38()]): CAST, offset=0, type_index=0",
+ "1: #39(): CAST, offset=0, type_index=0",
+ "2: #39(): CAST, offset=6, type_index=0",
+ "3: #36(#37=[@#38(),@#38()]): CAST, offset=6, type_index=0",
+ "4: #40(#37=[@#39(),@#39()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "5: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeInvisibleTypeAnnotations:",
+ "0: #39(): METHOD_RETURN",
+ "1: #36(#37=[@#38(),@#38()]): METHOD_RETURN",
+ "2: #40(#37=[@#39(),@#39()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "3: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
+ "4: #39(): METHOD_FORMAL_PARAMETER, param_index=1",
+ "5: #38(): METHOD_FORMAL_PARAMETER, param_index=1"
+ );
}
}
@TestCase
public static class TC15 extends RepeatingTypeAnnotations {
public TC15() {
- setSrc(" public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
+ setSrc(" /* TC15 */ ",
+ " public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {",
" @C @C @A String ls = (@A @A @C String) o;",
" return (@C @B @B String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
- "0: #36(): METHOD_RETURN",
- "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
- "2: #36(): CAST, offset=0",
- "3: #36(): CAST, offset=6",
- "4: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
- "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN",
- "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0",
- "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #42(): METHOD_FORMAL_PARAMETER, param_index=1",
- "4: #40(#38=[@#41(),@#41()]): CAST, offset=0",
- "5: #43(#38=[@#42(),@#42()]): CAST, offset=6",
- "6: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+ verify(
+ "RuntimeVisibleTypeAnnotations:",
+ "0: #36(): CAST, offset=0, type_index=0",
+ "1: #36(): CAST, offset=6, type_index=0",
+ "2: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeInvisibleTypeAnnotations:",
+ "0: #40(#38=[@#41(),@#41()]): CAST, offset=0, type_index=0",
+ "1: #42(#38=[@#43(),@#43()]): CAST, offset=6, type_index=0",
+ "2: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeVisibleTypeAnnotations:",
+ "0: #36(): METHOD_RETURN",
+ "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0",
+ "RuntimeInvisibleTypeAnnotations:",
+ "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN",
+ "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0",
+ "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1",
+ "3: #43(): METHOD_FORMAL_PARAMETER, param_index=1"
+ );
}
}
@TestCase
public static class TC16 extends RepeatingTypeAnnotations {
public TC16() {
- setSrc(" public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
+ setSrc(" /* TC16 */ ",
+ " public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {",
" @A @B @C String ls = (@C @A @B String) o;",
" return (@B @A @C String) o;",
" }");
- verify("RuntimeInvisibleTypeAnnotations",
- "RuntimeVisibleTypeAnnotations",
+ verify(
+ "RuntimeVisibleTypeAnnotations:",
+ "0: #36(): CAST, offset=0, type_index=0",
+ "1: #36(): CAST, offset=6, type_index=0",
+ "2: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeInvisibleTypeAnnotations:",
+ "0: #38(): CAST, offset=0, type_index=0",
+ "1: #39(): CAST, offset=0, type_index=0",
+ "2: #39(): CAST, offset=6, type_index=0",
+ "3: #38(): CAST, offset=6, type_index=0",
+ "4: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "5: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeVisibleTypeAnnotations:",
"0: #36(): METHOD_RETURN",
"1: #36(): METHOD_FORMAL_PARAMETER, param_index=0",
"2: #36(): METHOD_FORMAL_PARAMETER, param_index=1",
- "3: #36(): CAST, offset=0",
- "4: #36(): CAST, offset=6",
- "5: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
+ "RuntimeInvisibleTypeAnnotations:",
"0: #38(): METHOD_RETURN",
"1: #39(): METHOD_RETURN",
"2: #38(): METHOD_FORMAL_PARAMETER, param_index=0",
"3: #39(): METHOD_FORMAL_PARAMETER, param_index=0",
- "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1",
- "5: #38(): CAST, offset=0",
- "6: #39(): CAST, offset=0",
- "7: #39(): CAST, offset=6",
- "8: #38(): CAST, offset=6",
- "9: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}",
- "10: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}");
+ "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1"
+ );
}
}
}
--- a/langtools/test/tools/javap/typeAnnotations/NewArray.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javap/typeAnnotations/NewArray.java Tue May 14 15:04:06 2013 -0700
@@ -27,10 +27,11 @@
/*
* @test NewArray
* @bug 6843077
- * @summary test that all type annotations are present in the classfile
+ * @summary Test type annotations on local array are in method's code attribute.
*/
public class NewArray {
+
public static void main(String[] args) throws Exception {
new NewArray().run();
}
@@ -40,10 +41,6 @@
File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile);
- test(cf);
- for (Field f : cf.fields) {
- test(cf, f);
- }
for (Method m: cf.methods) {
test(cf, m);
}
@@ -55,66 +52,34 @@
System.out.println("PASSED");
}
- void test(ClassFile cf) {
- test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
- test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
- }
-
void test(ClassFile cf, Method m) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
}
- void test(ClassFile cf, Field m) {
- test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
- test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
- }
-
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
- void test(ClassFile cf, String name, boolean visible) {
- int index = cf.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = cf.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
- }
- }
+ void test(ClassFile cf, Method m, String name, boolean visible) {
+ Attribute attr = null;
+ Code_attribute cAttr = null;
+ RuntimeTypeAnnotations_attribute tAttr = null;
- // test the result of Attributes.getIndex according to expectations
- // encoded in the method's name
- void test(ClassFile cf, Method m, String name, boolean visible) {
- int index = m.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = m.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
- }
- }
-
- // test the result of Attributes.getIndex according to expectations
- // encoded in the method's name
- void test(ClassFile cf, Field m, String name, boolean visible) {
- int index = m.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = m.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
+ int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = m.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if(index!= -1) {
+ attr = cAttr.attributes.get(index);
+ assert attr instanceof RuntimeTypeAnnotations_attribute;
+ tAttr = (RuntimeTypeAnnotations_attribute)attr;
+ all += tAttr.annotations.length;
+ if (visible)
+ visibles += tAttr.annotations.length;
+ else
+ invisibles += tAttr.annotations.length;
+ }
}
}
@@ -124,14 +89,12 @@
out.println("import java.lang.annotation.*;");
out.println("import java.util.*;");
out.println("class Test { ");
- out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
- out.println(" @interface A { }");
-
- out.println(" void test() {");
- out.println(" Object a = new @A String @A [5] @A [];");
- out.println(" Object b = new @A String @A [5] @A [3];");
- out.println(" Object c = new @A String @A [] @A [] {};");
- out.println(" }");
+ out.println(" @Target(ElementType.TYPE_USE) @interface A { }");
+ out.println(" void test() {");
+ out.println(" Object a = new @A String @A [5] @A [];");
+ out.println(" Object b = new @A String @A [5] @A [3];");
+ out.println(" Object c = new @A String @A [] @A [] {};");
+ out.println(" }");
out.println("}");
out.close();
--- a/langtools/test/tools/javap/typeAnnotations/Presence.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javap/typeAnnotations/Presence.java Tue May 14 15:04:06 2013 -0700
@@ -91,17 +91,40 @@
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
void test(ClassFile cf, Method m, String name, boolean visible) {
+ Attribute attr = null;
+ Code_attribute cAttr = null;
+ RuntimeTypeAnnotations_attribute tAttr = null;
+
+ // collect annotations attributes on method
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
- Attribute attr = m.attributes.get(index);
+ attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+ tAttr = (RuntimeTypeAnnotations_attribute)attr;
all += tAttr.annotations.length;
if (visible)
visibles += tAttr.annotations.length;
else
invisibles += tAttr.annotations.length;
}
+ // collect annotations from method's code attribute
+ index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = m.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if(index!= -1) {
+ attr = cAttr.attributes.get(index);
+ assert attr instanceof RuntimeTypeAnnotations_attribute;
+ tAttr = (RuntimeTypeAnnotations_attribute)attr;
+ all += tAttr.annotations.length;
+ if (visible)
+ visibles += tAttr.annotations.length;
+ else
+ invisibles += tAttr.annotations.length;
+ }
+ }
}
// test the result of Attributes.getIndex according to expectations
@@ -121,12 +144,12 @@
}
File writeTestFile() throws IOException {
- File f = new File("Test.java");
+ File f = new File("TestPresence.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("import java.util.*;");
out.println("import java.lang.annotation.*;");
- out.println("class Test<@Test.A T extends @Test.A List<@Test.A String>> { ");
+ out.println("class TestPresence<@TestPresence.A T extends @TestPresence.A List<@TestPresence.A String>> { ");
out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
out.println(" @interface A { }");
@@ -134,7 +157,7 @@
out.println(" <@A TM extends @A List<@A String>>");
out.println(" Map<@A String, @A List<@A String>>");
- out.println(" method(@A Test<T> this, List<@A String> @A [] param1, String @A [] @A ... param2)");
+ out.println(" method(@A TestPresence<T> this, List<@A String> @A [] param1, String @A [] @A ... param2)");
out.println(" throws @A Exception {");
out.println(" @A String lc1 = null;");
out.println(" @A List<@A String> lc2 = null;");
--- a/langtools/test/tools/javap/typeAnnotations/TypeCasts.java Tue May 14 13:55:35 2013 -0700
+++ b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java Tue May 14 15:04:06 2013 -0700
@@ -41,10 +41,6 @@
File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile);
- test(cf);
- for (Field f : cf.fields) {
- test(cf, f);
- }
for (Method m: cf.methods) {
test(cf, m);
}
@@ -56,68 +52,37 @@
System.out.println("PASSED");
}
- void test(ClassFile cf) {
- test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
- test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
- }
-
void test(ClassFile cf, Method m) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
}
- void test(ClassFile cf, Field m) {
- test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
- test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
- }
-
- // test the result of Attributes.getIndex according to expectations
- // encoded in the method's name
- void test(ClassFile cf, String name, boolean visible) {
- int index = cf.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = cf.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
- }
- }
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
void test(ClassFile cf, Method m, String name, boolean visible) {
- int index = m.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = m.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
+ Attribute attr = null;
+ Code_attribute cAttr = null;
+
+ int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
+ if(index!= -1) {
+ attr = m.attributes.get(index);
+ assert attr instanceof Code_attribute;
+ cAttr = (Code_attribute)attr;
+ index = cAttr.attributes.getIndex(cf.constant_pool, name);
+ if(index!= -1) {
+ attr = cAttr.attributes.get(index);
+ assert attr instanceof RuntimeTypeAnnotations_attribute;
+ RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
+ all += tAttr.annotations.length;
+ if (visible)
+ visibles += tAttr.annotations.length;
+ else
+ invisibles += tAttr.annotations.length;
+ }
}
}
- // test the result of Attributes.getIndex according to expectations
- // encoded in the method's name
- void test(ClassFile cf, Field m, String name, boolean visible) {
- int index = m.attributes.getIndex(cf.constant_pool, name);
- if (index != -1) {
- Attribute attr = m.attributes.get(index);
- assert attr instanceof RuntimeTypeAnnotations_attribute;
- RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
- all += tAttr.annotations.length;
- if (visible)
- visibles += tAttr.annotations.length;
- else
- invisibles += tAttr.annotations.length;
- }
- }
File writeTestFile() throws IOException {
@@ -125,8 +90,7 @@
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("import java.lang.annotation.*;");
out.println("class Test { ");
- out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})");
- out.println(" @interface A { }");
+ out.println(" @Target(ElementType.TYPE_USE) @interface A { }");
out.println(" void emit() {");
out.println(" Object o = null;");