# HG changeset patch # User jjg # Date 1358976444 28800 # Node ID ee1eebe7e210eeebbf921e53fac635c7752f9060 # Parent 5a8d00abf076c62ab4b7ddf5051d011b40450a98 8006775: JSR 308: Compiler changes in JDK8 Reviewed-by: jjg Contributed-by: mernst@cs.washington.edu, wmdietl@cs.washington.edu, mpapi@csail.mit.edu, mahmood@notnoop.com diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/javadoc/AnnotatedType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/javadoc/AnnotatedType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,45 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.javadoc; + + +/** + * Represents an annotated type. + * For example: + *
+ *      {@code @NonNull String}
+ *      {@code @Positive int}
+ * 
+ * + * @author Mahmood Ali + * @since 1.8 + */ +public interface AnnotatedType extends Type { + + AnnotationDesc[] annotations(); + + Type underlyingType(); +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java --- a/langtools/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -88,6 +88,15 @@ Parameter[] parameters(); /** + * Get the receiver annotations of this executable element. + * Return an empty array if there are none. + * + * @return the receiver annotations of this executable element. + * @since 1.8 + */ + AnnotationDesc[] receiverAnnotations(); + + /** * Return the throws tags in this method. * * @return an array of ThrowTag containing all @exception diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/javadoc/Type.java --- a/langtools/src/share/classes/com/sun/javadoc/Type.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/javadoc/Type.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -142,6 +142,16 @@ WildcardType asWildcardType(); /** + * Returns this type as a AnnotatedType if it represents + * an annotated type. + * + * @return a AnnotatedType if the type if an annotated type, + * or null if it is not + * @since 1.8 + */ + AnnotatedType asAnnotatedType(); + + /** * Return this type as an AnnotationTypeDoc if it represents * an annotation type. Array dimensions are ignored. * diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/javadoc/TypeVariable.java --- a/langtools/src/share/classes/com/sun/javadoc/TypeVariable.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/javadoc/TypeVariable.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 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 @@ -55,4 +55,11 @@ * which this type variable is declared. */ ProgramElementDoc owner(); + + /** + * Get the annotations of this program element. + * Return an empty array if there are none. + */ + public AnnotationDesc[] annotations(); + } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/tree/AnnotatedTypeTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/AnnotatedTypeTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2008, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.source.tree; + +import java.util.List; + +/** + * A tree node for an annotated type + * + * For example: + *
+ *    {@code @}annotationType String
+ *    {@code @}annotationType ( arguments ) Date
+ * 
+ * + * @see "JSR 308: Annotations on Java Types" + * + * @author Mahmood Ali + * @since 1.8 + */ +public interface AnnotatedTypeTree extends ExpressionTree { + List getAnnotations(); + ExpressionTree getUnderlyingType(); +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/tree/MethodTree.java --- a/langtools/src/share/classes/com/sun/source/tree/MethodTree.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/MethodTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -52,6 +52,7 @@ Tree getReturnType(); List getTypeParameters(); List getParameters(); + VariableTree getReceiverParameter(); List getThrows(); BlockTree getBody(); Tree getDefaultValue(); // for annotation types diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/tree/Tree.java --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -46,12 +46,21 @@ */ public enum Kind { + ANNOTATED_TYPE(AnnotatedTypeTree.class), + /** - * Used for instances of {@link AnnotationTree}. + * Used for instances of {@link AnnotationTree} + * representing declaration annotations. */ ANNOTATION(AnnotationTree.class), /** + * Used for instances of {@link AnnotationTree} + * representing type annotations. + */ + TYPE_ANNOTATION(AnnotationTree.class), + + /** * Used for instances of {@link ArrayAccessTree}. */ ARRAY_ACCESS(ArrayAccessTree.class), diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -57,6 +57,7 @@ * @since 1.6 */ public interface TreeVisitor { + R visitAnnotatedType(AnnotatedTypeTree node, P p); R visitAnnotation(AnnotationTree node, P p); R visitMethodInvocation(MethodInvocationTree node, P p); R visitAssert(AssertTree node, P p); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java --- a/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -47,4 +47,5 @@ public interface TypeParameterTree extends Tree { Name getName(); List getBounds(); + List getAnnotations(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -260,6 +260,10 @@ return defaultAction(node, p); } + public R visitAnnotatedType(AnnotatedTypeTree node, P p) { + return defaultAction(node, p); + } + public R visitErroneous(ErroneousTree node, P p) { return defaultAction(node, p); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/util/TaskEvent.java --- a/langtools/src/share/classes/com/sun/source/util/TaskEvent.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/util/TaskEvent.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -60,7 +60,7 @@ **/ GENERATE, /** - * For events relating to overall annotaion processing. + * For events relating to overall annotation processing. **/ ANNOTATION_PROCESSING, /** diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/source/util/TreeScanner.java --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -138,6 +138,7 @@ r = scanAndReduce(node.getReturnType(), p, r); r = scanAndReduce(node.getTypeParameters(), p, r); r = scanAndReduce(node.getParameters(), p, r); + r = scanAndReduce(node.getReceiverParameter(), p, r); r = scanAndReduce(node.getThrows(), p, r); r = scanAndReduce(node.getBody(), p, r); r = scanAndReduce(node.getDefaultValue(), p, r); @@ -376,7 +377,8 @@ } public R visitTypeParameter(TypeParameterTree node, P p) { - R r = scan(node.getBounds(), p); + R r = scan(node.getAnnotations(), p); + r = scanAndReduce(node.getBounds(), p, r); return r; } @@ -394,6 +396,12 @@ return r; } + public R visitAnnotatedType(AnnotatedTypeTree node, P p) { + R r = scan(node.getAnnotations(), p); + r = scanAndReduce(node.getUnderlyingType(), p, r); + return r; + } + public R visitOther(Tree node, P p) { return null; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/Attribute.java --- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -56,6 +56,8 @@ public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations"; public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations"; public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations"; + public static final String RuntimeVisibleTypeAnnotations = "RuntimeVisibleTypeAnnotations"; + public static final String RuntimeInvisibleTypeAnnotations = "RuntimeInvisibleTypeAnnotations"; public static final String Signature = "Signature"; public static final String SourceDebugExtension = "SourceDebugExtension"; public static final String SourceFile = "SourceFile"; @@ -120,6 +122,8 @@ standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class); standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class); standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class); + standardAttributes.put(RuntimeVisibleTypeAnnotations, RuntimeVisibleTypeAnnotations_attribute.class); + standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class); standardAttributes.put(Signature, Signature_attribute.class); standardAttributes.put(SourceID, SourceID_attribute.class); } @@ -178,6 +182,8 @@ R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p); R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p); R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p); + R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p); + R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p); R visitSignature(Signature_attribute attr, P p); R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p); R visitSourceFile(SourceFile_attribute attr, P p); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -498,6 +498,16 @@ return null; } + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, ClassOutputStream out) { + annotationWriter.write(attr.annotations, out); + return null; + } + + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, ClassOutputStream out) { + annotationWriter.write(attr.annotations, out); + return null; + } + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) { out.writeByte(attr.parameter_annotations.length); for (Annotation[] annos: attr.parameter_annotations) @@ -657,6 +667,12 @@ write(anno, out); } + public void write(TypeAnnotation[] annos, ClassOutputStream out) { + out.writeShort(annos.length); + for (TypeAnnotation anno: annos) + write(anno, out); + } + public void write(Annotation anno, ClassOutputStream out) { out.writeShort(anno.type_index); out.writeShort(anno.element_value_pairs.length); @@ -664,6 +680,11 @@ write(p, out); } + public void write(TypeAnnotation anno, ClassOutputStream out) { + write(anno.position, out); + write(anno.annotation, out); + } + public void write(element_value_pair pair, ClassOutputStream out) { out.writeShort(pair.element_name_index); write(pair.value, out); @@ -702,5 +723,89 @@ return null; } + // TODO: Move this to TypeAnnotation to be closer with similar logic? + private void write(TypeAnnotation.Position p, ClassOutputStream out) { + out.writeByte(p.type.targetTypeValue()); + switch (p.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + out.writeShort(p.offset); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + int table_length = p.lvarOffset.length; + out.writeShort(table_length); + for (int i = 0; i < table_length; ++i) { + out.writeShort(1); // for table length + out.writeShort(p.lvarOffset[i]); + out.writeShort(p.lvarLength[i]); + out.writeShort(p.lvarIndex[i]); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + out.writeByte(p.exception_index); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameters + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + out.writeByte(p.parameter_index); + break; + // type parameters bounds + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + out.writeByte(p.parameter_index); + out.writeByte(p.bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + out.writeByte(p.type_index); + break; + // throws + case THROWS: + out.writeByte(p.type_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + out.writeByte(p.parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + out.writeShort(p.offset); + out.writeByte(p.type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + out.writeByte(p.parameter_index); + break; + case UNKNOWN: + throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("ClassWriter: Unknown target type for position: " + p); + } + + { // Append location data for generics/arrays. + // TODO: check for overrun? + out.writeByte((byte)p.location.size()); + for (int i : TypeAnnotation.Position.getBinaryFromTypePath(p.location)) + out.writeByte((byte)i); + } + } } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import java.io.IOException; + +/** + * See JSR 308 specification, Section 3. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class RuntimeInvisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute { + RuntimeInvisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length) + throws IOException, Annotation.InvalidAnnotation { + super(cr, name_index, length); + } + + public RuntimeInvisibleTypeAnnotations_attribute(ConstantPool cp, TypeAnnotation[] annotations) + throws ConstantPoolException { + this(cp.getUTF8Index(Attribute.RuntimeInvisibleTypeAnnotations), annotations); + } + + public RuntimeInvisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) { + super(name_index, annotations); + } + + public R accept(Visitor visitor, P p) { + return visitor.visitRuntimeInvisibleTypeAnnotations(this, p); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import java.io.IOException; + +/** + * See JSR 308 specification, Section 3. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public abstract class RuntimeTypeAnnotations_attribute extends Attribute { + protected RuntimeTypeAnnotations_attribute(ClassReader cr, int name_index, int length) + throws IOException, Annotation.InvalidAnnotation { + super(name_index, length); + int num_annotations = cr.readUnsignedShort(); + annotations = new TypeAnnotation[num_annotations]; + for (int i = 0; i < annotations.length; i++) + annotations[i] = new TypeAnnotation(cr); + } + + protected RuntimeTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) { + super(name_index, length(annotations)); + this.annotations = annotations; + } + + private static int length(TypeAnnotation[] annos) { + int n = 2; + for (TypeAnnotation anno: annos) + n += anno.length(); + return n; + } + + public final TypeAnnotation[] annotations; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import java.io.IOException; + +/** + * See JSR 308 specification, Section 3. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class RuntimeVisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute { + RuntimeVisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length) + throws IOException, Annotation.InvalidAnnotation { + super(cr, name_index, length); + } + + public RuntimeVisibleTypeAnnotations_attribute(ConstantPool cp, TypeAnnotation[] annotations) + throws ConstantPoolException { + this(cp.getUTF8Index(Attribute.RuntimeVisibleTypeAnnotations), annotations); + } + + public RuntimeVisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) { + super(name_index, annotations); + } + + public R accept(Visitor visitor, P p) { + return visitor.visitRuntimeVisibleTypeAnnotations(this, p); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,656 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.sun.tools.classfile.TypeAnnotation.Position.TypePathEntry; + +/** + * See JSR 308 specification, Section 3. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class TypeAnnotation { + TypeAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation { + constant_pool = cr.getConstantPool(); + position = read_position(cr); + annotation = new Annotation(cr); + } + + public TypeAnnotation(ConstantPool constant_pool, + Annotation annotation, Position position) { + this.constant_pool = constant_pool; + this.position = position; + this.annotation = annotation; + } + + public int length() { + int n = annotation.length(); + n += position_length(position); + return n; + } + + @Override + public String toString() { + try { + return "@" + constant_pool.getUTF8Value(annotation.type_index).toString().substring(1) + + " pos: " + position.toString(); + } catch (Exception e) { + e.printStackTrace(); + return e.toString(); + } + } + + public final ConstantPool constant_pool; + public final Position position; + public final Annotation annotation; + + private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation { + // Copied from ClassReader + int tag = cr.readUnsignedByte(); // TargetType tag is a byte + if (!TargetType.isValidTargetTypeValue(tag)) + throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag)); + + TargetType type = TargetType.fromTargetTypeValue(tag); + + Position position = new Position(); + position.type = type; + + switch (type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + position.offset = cr.readUnsignedShort(); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + int table_length = cr.readUnsignedShort(); + position.lvarOffset = new int[table_length]; + position.lvarLength = new int[table_length]; + position.lvarIndex = new int[table_length]; + for (int i = 0; i < table_length; ++i) { + position.lvarOffset[i] = cr.readUnsignedShort(); + position.lvarLength[i] = cr.readUnsignedShort(); + position.lvarIndex[i] = cr.readUnsignedShort(); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + position.exception_index = cr.readUnsignedByte(); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + position.parameter_index = cr.readUnsignedByte(); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + position.parameter_index = cr.readUnsignedByte(); + position.bound_index = cr.readUnsignedByte(); + break; + // class extends or implements clause + case CLASS_EXTENDS: + int in = cr.readUnsignedShort(); + if (in == 0xFFFF) + in = -1; + position.type_index = in; + break; + // throws + case THROWS: + position.type_index = cr.readUnsignedShort(); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + position.parameter_index = cr.readUnsignedByte(); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + position.offset = cr.readUnsignedShort(); + position.type_index = cr.readUnsignedByte(); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + position.parameter_index = cr.readUnsignedByte(); + break; + case UNKNOWN: + throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("TypeAnnotation: Unknown target type: " + type); + } + + { // Write type path + int len = cr.readUnsignedByte(); + List loc = new ArrayList(len); + for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i) + loc.add(cr.readUnsignedByte()); + position.location = Position.getTypePathFromBinary(loc); + } + return position; + } + + private static int position_length(Position pos) { + int n = 0; + n += 1; // TargetType tag is a byte + switch (pos.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + n += 2; + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + n += 2; // table_length; + int table_length = pos.lvarOffset.length; + n += 2 * table_length; // offset + n += 2 * table_length; // length; + n += 2 * table_length; // index + break; + // exception parameter + case EXCEPTION_PARAMETER: + n += 1; // exception_index + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + n += 1; // parameter_index; + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + n += 1; // parameter_index + n += 1; // bound_index + break; + // class extends or implements clause + case CLASS_EXTENDS: + n += 2; // type_index + break; + // throws + case THROWS: + n += 2; // type_index + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + n += 1; // parameter_index + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + n += 2; // offset + n += 1; // type index + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + n += 1; // parameter_index + break; + case UNKNOWN: + throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type); + } + + { + n += 1; // length + n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array + } + + return n; + } + + // Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition + public static class Position { + public enum TypePathEntryKind { + ARRAY(0), + INNER_TYPE(1), + WILDCARD(2), + TYPE_ARGUMENT(3); + + public final int tag; + + private TypePathEntryKind(int tag) { + this.tag = tag; + } + } + + public static class TypePathEntry { + /** The fixed number of bytes per TypePathEntry. */ + public static final int bytesPerEntry = 2; + + public final TypePathEntryKind tag; + public final int arg; + + public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY); + public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE); + public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD); + + private TypePathEntry(TypePathEntryKind tag) { + if (!(tag == TypePathEntryKind.ARRAY || + tag == TypePathEntryKind.INNER_TYPE || + tag == TypePathEntryKind.WILDCARD)) { + throw new AssertionError("Invalid TypePathEntryKind: " + tag); + } + this.tag = tag; + this.arg = 0; + } + + public TypePathEntry(TypePathEntryKind tag, int arg) { + if (tag != TypePathEntryKind.TYPE_ARGUMENT) { + throw new AssertionError("Invalid TypePathEntryKind: " + tag); + } + this.tag = tag; + this.arg = arg; + } + + public static TypePathEntry fromBinary(int tag, int arg) { + if (arg != 0 && tag != TypePathEntryKind.TYPE_ARGUMENT.tag) { + throw new AssertionError("Invalid TypePathEntry tag/arg: " + tag + "/" + arg); + } + switch (tag) { + case 0: + return ARRAY; + case 1: + return INNER_TYPE; + case 2: + return WILDCARD; + case 3: + return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg); + default: + throw new AssertionError("Invalid TypePathEntryKind tag: " + tag); + } + } + + @Override + public String toString() { + return tag.toString() + + (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : ""); + } + + @Override + public boolean equals(Object other) { + if (! (other instanceof TypePathEntry)) { + return false; + } + TypePathEntry tpe = (TypePathEntry) other; + return this.tag == tpe.tag && this.arg == tpe.arg; + } + + @Override + public int hashCode() { + return this.tag.hashCode() * 17 + this.arg; + } + } + + public TargetType type = TargetType.UNKNOWN; + + // For generic/array types. + // TODO: or should we use null? Noone will use this object. + public List location = new ArrayList(0); + + // Tree position. + public int pos = -1; + + // For typecasts, type tests, new (and locals, as start_pc). + public boolean isValidOffset = false; + public int offset = -1; + + // For locals. arrays same length + public int[] lvarOffset = null; + public int[] lvarLength = null; + public int[] lvarIndex = null; + + // For type parameter bound + public int bound_index = Integer.MIN_VALUE; + + // For type parameter and method parameter + public int parameter_index = Integer.MIN_VALUE; + + // For class extends, implements, and throws clauses + public int type_index = Integer.MIN_VALUE; + + // For exception parameters, index into exception table + public int exception_index = Integer.MIN_VALUE; + + public Position() {} + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + sb.append(type); + + switch (type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + sb.append(", offset = "); + sb.append(offset); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + if (lvarOffset == null) { + sb.append(", lvarOffset is null!"); + break; + } + sb.append(", {"); + for (int i = 0; i < lvarOffset.length; ++i) { + if (i != 0) sb.append("; "); + sb.append("start_pc = "); + sb.append(lvarOffset[i]); + sb.append(", length = "); + sb.append(lvarLength[i]); + sb.append(", index = "); + sb.append(lvarIndex[i]); + } + sb.append("}"); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + sb.append(", param_index = "); + sb.append(parameter_index); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + sb.append(", param_index = "); + sb.append(parameter_index); + sb.append(", bound_index = "); + sb.append(bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + sb.append(", type_index = "); + sb.append(type_index); + break; + // throws + case THROWS: + sb.append(", type_index = "); + sb.append(type_index); + break; + // exception parameter + case EXCEPTION_PARAMETER: + sb.append(", exception_index = "); + sb.append(exception_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + sb.append(", param_index = "); + sb.append(parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + sb.append(", offset = "); + sb.append(offset); + sb.append(", type_index = "); + sb.append(type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + // TODO: also needs an offset? + sb.append(", param_index = "); + sb.append(parameter_index); + break; + case UNKNOWN: + sb.append(", position UNKNOWN!"); + break; + default: + throw new AssertionError("Unknown target type: " + type); + } + + // Append location data for generics/arrays. + if (!location.isEmpty()) { + sb.append(", location = ("); + sb.append(location); + sb.append(")"); + } + + sb.append(", pos = "); + sb.append(pos); + + sb.append(']'); + return sb.toString(); + } + + /** + * Indicates whether the target tree of the annotation has been optimized + * away from classfile or not. + * @return true if the target has not been optimized away + */ + public boolean emitToClassfile() { + return !type.isLocal() || isValidOffset; + } + + /** + * Decode the binary representation for a type path and set + * the {@code location} field. + * + * @param list The bytecode representation of the type path. + */ + public static List getTypePathFromBinary(List list) { + List loc = new ArrayList(list.size() / TypePathEntry.bytesPerEntry); + int idx = 0; + while (idx < list.size()) { + if (idx + 1 == list.size()) { + throw new AssertionError("Could not decode type path: " + list); + } + loc.add(TypePathEntry.fromBinary(list.get(idx), list.get(idx + 1))); + idx += 2; + } + return loc; + } + + public static List getBinaryFromTypePath(List locs) { + List loc = new ArrayList(locs.size() * TypePathEntry.bytesPerEntry); + for (TypePathEntry tpe : locs) { + loc.add(tpe.tag.tag); + loc.add(tpe.arg); + } + return loc; + } + } + + // Code duplicated from com.sun.tools.javac.code.TargetType + // The IsLocal flag could be removed here. + public enum TargetType { + /** For annotations on a class type parameter declaration. */ + CLASS_TYPE_PARAMETER(0x00), + + /** For annotations on a method type parameter declaration. */ + METHOD_TYPE_PARAMETER(0x01), + + /** For annotations on the type of an "extends" or "implements" clause. */ + CLASS_EXTENDS(0x10), + + /** For annotations on a bound of a type parameter of a class. */ + CLASS_TYPE_PARAMETER_BOUND(0x11), + + /** For annotations on a bound of a type parameter of a method. */ + METHOD_TYPE_PARAMETER_BOUND(0x12), + + /** For annotations on a field. */ + FIELD(0x13), + + /** For annotations on a method return type. */ + METHOD_RETURN(0x14), + + /** For annotations on the method receiver. */ + METHOD_RECEIVER(0x15), + + /** For annotations on a method parameter. */ + METHOD_FORMAL_PARAMETER(0x16), + + /** For annotations on a throws clause in a method declaration. */ + THROWS(0x17), + + /** For annotations on a local variable. */ + LOCAL_VARIABLE(0x40, true), + + /** For annotations on a resource variable. */ + RESOURCE_VARIABLE(0x41, true), + + /** For annotations on an exception parameter. */ + EXCEPTION_PARAMETER(0x42, true), + + /** For annotations on a typecast. */ + CAST(0x43, true), + + /** For annotations on a type test. */ + INSTANCEOF(0x44, true), + + /** For annotations on an object creation expression. */ + NEW(0x45, true), + + /** For annotations on a type argument of an object creation expression. */ + CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true), + + /** For annotations on a type argument of a method call. */ + METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true), + + /** For annotations on a lambda parameter type. */ + LAMBDA_FORMAL_PARAMETER(0x48, true), + + /** For annotations on a method reference. */ + METHOD_REFERENCE(0x49, true), + + /** For annotations on a type argument of a method reference. */ + METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true), + + /** For annotations with an unknown target. */ + UNKNOWN(0xFF); + + private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50; + + private final int targetTypeValue; + private final boolean isLocal; + + private TargetType(int targetTypeValue) { + this(targetTypeValue, false); + } + + private TargetType(int targetTypeValue, boolean isLocal) { + if (targetTypeValue < 0 + || targetTypeValue > 255) + throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue)); + this.targetTypeValue = targetTypeValue; + this.isLocal = isLocal; + } + + /** + * Returns whether or not this TargetType represents an annotation whose + * target is exclusively a tree in a method body + * + * Note: wildcard bound targets could target a local tree and a class + * member declaration signature tree + */ + public boolean isLocal() { + return isLocal; + } + + public int targetTypeValue() { + return this.targetTypeValue; + } + + private static final TargetType[] targets; + + static { + targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1]; + TargetType[] alltargets = values(); + for (TargetType target : alltargets) { + if (target.targetTypeValue != UNKNOWN.targetTypeValue) + targets[target.targetTypeValue] = target; + } + for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) { + if (targets[i] == null) + targets[i] = UNKNOWN; + } + } + + public static boolean isValidTargetTypeValue(int tag) { + if (tag == UNKNOWN.targetTypeValue) + return true; + return (tag >= 0 && tag < targets.length); + } + + public static TargetType fromTargetTypeValue(int tag) { + if (tag == UNKNOWN.targetTypeValue) + return UNKNOWN; + + if (tag < 0 || tag >= targets.length) + throw new AssertionError("Unknown TargetType: " + tag); + return targets[tag]; + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -139,6 +139,15 @@ } } + protected void addReceiverAnnotations(ExecutableMemberDoc member, + Content tree) { + if (member.receiverAnnotations().length > 0) { + tree.addContent(writer.getSpace()); + writer.addReceiverAnnotationInfo(member, tree); + } + } + + /** * Add all the parameters for the executable member. * diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -137,6 +137,7 @@ addName(constructor.name(), pre); } addParameters(constructor, pre); + writer.addReceiverAnnotationInfo(constructor, pre); addExceptions(constructor, pre); return pre; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -1730,6 +1730,17 @@ } /** + * Add the annotation types of the executable receiver. + * + * @param method the executable to write the receiver annotations for. + * @param htmltree the documentation tree to which the annotation info will be + * added + */ + public void addReceiverAnnotationInfo(ExecutableMemberDoc method, Content htmltree) { + addAnnotationInfo(method, method.receiverAnnotations(), htmltree); + } + + /** * Adds the annotatation types for the given doc. * * @param doc the package to write annotations for @@ -1799,6 +1810,26 @@ * documented. */ private List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) { + return getAnnotations(indent, descList, linkBreak, true); + } + + /** + * Return the string representations of the annotation types for + * the given doc. + * + * A {@code null} {@code elementType} indicates that all the + * annotations should be returned without any filtering. + * + * @param indent the number of extra spaces to indent the annotations. + * @param descList the array of {@link AnnotationDesc}. + * @param linkBreak if true, add new line between each member value. + * @param elementType the type of targeted element (used for filtering + * type annotations from declaration annotations) + * @return an array of strings representing the annotations being + * documented. + */ + public List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak, + boolean isJava5DeclarationLocation) { List results = new ArrayList(); StringBuilder annotation; for (int i = 0; i < descList.length; i++) { @@ -1812,6 +1843,11 @@ (!isAnnotationDocumented && !isContainerDocumented)) { continue; } + /* TODO: check logic here to correctly handle declaration + * and type annotations. + if (Util.isDeclarationAnnotation(annotationDoc, isJava5DeclarationLocation)) { + continue; + }*/ annotation = new StringBuilder(); isAnnotationDocumented = false; LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -25,6 +25,8 @@ package com.sun.tools.doclets.formats.html; +import java.util.List; + import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.*; @@ -123,11 +125,50 @@ typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds; typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks; typeLinkInfo.linkToSelf = linkInfo.linkToSelf; + typeLinkInfo.isJava5DeclarationLocation = false; LinkOutput output = getLinkOutput(typeLinkInfo); ((LinkInfoImpl) linkInfo).displayLength += typeLinkInfo.displayLength; return output; } + protected LinkOutput getTypeAnnotationLink(LinkInfo linkInfo, + AnnotationDesc annotation) { + throw new RuntimeException("Not implemented yet!"); + } + + public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) { + LinkOutput output = getOutputInstance(); + AnnotationDesc[] annotations; + if (linkInfo.type instanceof AnnotatedType) { + annotations = linkInfo.type.asAnnotatedType().annotations(); + } else if (linkInfo.type instanceof TypeVariable) { + annotations = linkInfo.type.asTypeVariable().annotations(); + } else { + return output; + } + + if (annotations.length == 0) + return output; + + List annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation); + + boolean isFirst = true; + for (String anno : annos) { + if (!isFirst) { + linkInfo.displayLength += 1; + output.append(" "); + isFirst = false; + } + output.append(anno); + } + if (!annos.isEmpty()) { + linkInfo.displayLength += 1; + output.append(" "); + } + + return output; + } + /** * Given a class, return the appropriate tool tip. * diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -459,6 +459,8 @@ case CONTEXT_RETURN_TYPE: case CONTEXT_SUMMARY_RETURN_TYPE: + excludeTypeBounds = true; + break; case CONTEXT_EXECUTABLE_MEMBER_PARAM: excludeTypeBounds = true; break; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -130,6 +130,7 @@ addName(method.name(), pre); } addParameters(method, pre); + addReceiverAnnotations(method, pre); addExceptions(method, pre); return pre; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -26,9 +26,11 @@ package com.sun.tools.doclets.internal.toolkit.util; import java.io.*; +import java.lang.annotation.ElementType; import java.util.*; import com.sun.javadoc.*; +import com.sun.javadoc.AnnotationDesc.ElementValuePair; import com.sun.tools.doclets.internal.toolkit.*; import javax.tools.StandardLocation; @@ -304,9 +306,7 @@ //Try walking the tree. addAllInterfaceTypes(results, superType, - superType instanceof ClassDoc ? - ((ClassDoc) superType).interfaceTypes() : - ((ParameterizedType) superType).interfaceTypes(), + interfaceTypesOf(superType), false, configuration); List resultsList = new ArrayList(results.values()); if (sort) { @@ -315,6 +315,14 @@ return resultsList; } + private static Type[] interfaceTypesOf(Type type) { + if (type instanceof AnnotatedType) + type = ((AnnotatedType)type).underlyingType(); + return type instanceof ClassDoc ? + ((ClassDoc)type).interfaceTypes() : + ((ParameterizedType)type).interfaceTypes(); + } + public static List getAllInterfaces(Type type, Configuration configuration) { return getAllInterfaces(type, configuration, true); } @@ -325,9 +333,7 @@ if (superType == null) return; addAllInterfaceTypes(results, superType, - superType instanceof ClassDoc ? - ((ClassDoc) superType).interfaceTypes() : - ((ParameterizedType) superType).interfaceTypes(), + interfaceTypesOf(superType), raw, configuration); } @@ -337,9 +343,7 @@ if (superType == null) return; addAllInterfaceTypes(results, superType, - superType instanceof ClassDoc ? - ((ClassDoc) superType).interfaceTypes() : - ((ParameterizedType) superType).interfaceTypes(), + interfaceTypesOf(superType), false, configuration); } @@ -363,6 +367,9 @@ results.put(superInterface.asClassDoc(), superInterface); } } + if (type instanceof AnnotatedType) + type = ((AnnotatedType)type).underlyingType(); + if (type instanceof ParameterizedType) findAllInterfaceTypes(results, (ParameterizedType) type, configuration); else if (((ClassDoc) type).typeParameters().length == 0) @@ -494,6 +501,57 @@ return false; } + private static boolean isDeclarationTarget(AnnotationDesc targetAnno) { + // The error recovery steps here are analogous to TypeAnnotations + ElementValuePair[] elems = targetAnno.elementValues(); + if (elems == null + || elems.length != 1 + || !"value".equals(elems[0].element().name()) + || !(elems[0].value().value() instanceof AnnotationValue[])) + return true; // error recovery + + AnnotationValue[] values = (AnnotationValue[])elems[0].value().value(); + for (int i = 0; i < values.length; i++) { + Object value = values[i].value(); + if (!(value instanceof FieldDoc)) + return true; // error recovery + + FieldDoc eValue = (FieldDoc)value; + if (Util.isJava5DeclarationElementType(eValue)) { + return true; + } + } + + return false; + } + + /** + * Returns true if the {@code annotationDoc} is to be treated + * as a declaration annotation, when targeting the + * {@code elemType} element type. + * + * @param annotationDoc the annotationDoc to check + * @param elemType the targeted elemType + * @return true if annotationDoc is a declaration annotation + */ + public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc, + boolean isJava5DeclarationLocation) { + if (!isJava5DeclarationLocation) + return false; + AnnotationDesc[] annotationDescList = annotationDoc.annotations(); + // Annotations with no target are treated as declaration as well + if (annotationDescList.length==0) + return true; + for (int i = 0; i < annotationDescList.length; i++) { + if (annotationDescList[i].annotationType().qualifiedName().equals( + java.lang.annotation.Target.class.getName())) { + if (isDeclarationTarget(annotationDescList[i])) + return true; + } + } + return false; + } + /** * Return true if this class is linkable and false if we can't link to the * desired class. @@ -662,4 +720,25 @@ } return false; } + + /** + * Test whether the given FieldDoc is one of the declaration annotation ElementTypes + * defined in Java 5. + * Instead of testing for one of the new enum constants added in Java 8, test for + * the old constants. This prevents bootstrapping problems. + * + * @param elt The FieldDoc to test + * @return true, iff the given ElementType is one of the constants defined in Java 5 + * @since 1.8 + */ + public static boolean isJava5DeclarationElementType(FieldDoc elt) { + return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) || + elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) || + elt.name().contentEquals(ElementType.FIELD.name()) || + elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) || + elt.name().contentEquals(ElementType.METHOD.name()) || + elt.name().contentEquals(ElementType.PACKAGE.name()) || + elt.name().contentEquals(ElementType.PARAMETER.name()) || + elt.name().contentEquals(ElementType.TYPE.name()); + } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -61,6 +61,11 @@ //Just a primitive. linkInfo.displayLength += type.typeName().length(); linkOutput.append(type.typeName()); + } else if (type.asAnnotatedType() != null) { + linkOutput.append(getTypeAnnotationLinks(linkInfo)); + linkInfo.type = type.asAnnotatedType().underlyingType(); + linkOutput.append(getLinkOutput(linkInfo)); + return linkOutput; } else if (type.asWildcardType() != null) { //Wildcard type. linkInfo.isTypeBound = true; @@ -82,6 +87,7 @@ linkOutput.append(getLinkOutput(linkInfo)); } } else if (type.asTypeVariable()!= null) { + linkOutput.append(getTypeAnnotationLinks(linkInfo)); linkInfo.isTypeBound = true; //A type variable. Doc owner = type.asTypeVariable().owner(); @@ -175,6 +181,9 @@ protected abstract LinkOutput getTypeParameterLink(LinkInfo linkInfo, Type typeParam); + protected abstract LinkOutput getTypeAnnotationLink(LinkInfo linkInfo, + AnnotationDesc annotation); + /** * Return the links to the type parameters. * @@ -226,6 +235,24 @@ return output; } + public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) { + LinkOutput output = getOutputInstance(); + if (linkInfo.type.asAnnotatedType() == null) + return output; + AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations(); + for (int i = 0; i < annotations.length; i++) { + if (i > 0) { + linkInfo.displayLength += 1; + output.append(" "); + } + output.append(getTypeAnnotationLink(linkInfo, annotations[i])); + } + + linkInfo.displayLength += 1; + output.append(" "); + return output; + } + /** * Return &lt;, which is used in type parameters. Override this * if your doclet uses something different. diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -69,6 +69,12 @@ public boolean isTypeBound = false; /** + * Whether the document element is in a Java 5 declaration + * location or not. + */ + public boolean isJava5DeclarationLocation = true; + + /** * The label for the link. */ public String label; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -48,7 +48,7 @@ * * An instance of this class can be in one of three states: * - * NOT_STARTED indicates that the Symbol this instance belongs to have not been + * NOT_STARTED indicates that the Symbol this instance belongs to has not been * annotated (yet). Specifically if the declaration is not annotated this * instance will never move past NOT_STARTED. You can never go back to * NOT_STARTED. @@ -59,7 +59,7 @@ * * "unnamed" this Annotations contains some attributes, possibly the final set. * While in this state you can only prepend or append to the attributes not set - * it directly. You can also move back to the IN_PROGRESS sate using reset(). + * it directly. You can also move back to the IN_PROGRESS state using reset(). * *

This is NOT part of any supported API. If you write code that depends * on this, you do so at your own risk. This code and its internal interfaces @@ -67,14 +67,21 @@ */ public class Annotations { - private static final List NOT_STARTED = List.of(null); - private static final List IN_PROGRESS = List.of(null); + private static final List DECL_NOT_STARTED = List.of(null); + private static final List DECL_IN_PROGRESS = List.of(null); + /* * This field should never be null */ - private List attributes = NOT_STARTED; + private List attributes = DECL_NOT_STARTED; + /* - * The Symbol this Annotations belong to + * This field should never be null + */ + private List type_attributes = List.nil(); + + /* + * The Symbol this Annotations instance belongs to */ private final Symbol sym; @@ -82,11 +89,15 @@ this.sym = sym; } - public List getAttributes() { - return filterSentinels(attributes); + public List getDeclarationAttributes() { + return filterDeclSentinels(attributes); } - public void setAttributes(List a) { + public List getTypeAttributes() { + return type_attributes; + } + + public void setDeclarationAttributes(List a) { Assert.check(pendingCompletion() || !isStarted()); if (a == null) { throw new NullPointerException(); @@ -94,31 +105,51 @@ attributes = a; } + public void setTypeAttributes(List a) { + if (a == null) { + throw new NullPointerException(); + } + type_attributes = a; + } + public void setAttributes(Annotations other) { if (other == null) { throw new NullPointerException(); } - setAttributes(other.getAttributes()); + setDeclarationAttributes(other.getDeclarationAttributes()); + setTypeAttributes(other.getTypeAttributes()); + } + + public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) { + Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK)); + this.setDeclarationAttributes(getAttributesForCompletion(ctx)); } - public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) { - Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK)); + public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) { + this.appendUniqueTypes(getAttributesForCompletion(ctx)); + } - Map> annotated = ctx.annotated; + private List getAttributesForCompletion( + final Annotate.AnnotateRepeatedContext ctx) { + + Map> annotated = ctx.annotated; boolean atLeastOneRepeated = false; - List buf = List.nil(); - for (ListBuffer lb : annotated.values()) { + List buf = List.nil(); + for (ListBuffer lb : annotated.values()) { if (lb.size() == 1) { buf = buf.prepend(lb.first()); } else { // repeated - buf = buf.prepend(new Placeholder(lb.toList(), sym)); + // This will break when other subtypes of Attributs.Compound + // are introduced, because PlaceHolder is a subtype of TypeCompound. + T res; + @SuppressWarnings("unchecked") + T ph = (T) new Placeholder(ctx, lb.toList(), sym); + res = ph; + buf = buf.prepend(res); atLeastOneRepeated = true; } } - // Add non-repeating attributes - setAttributes(buf.reverse()); - if (atLeastOneRepeated) { // The Symbol s is now annotated with a combination of // finished non-repeating annotations and placeholders for @@ -138,7 +169,6 @@ // Queue a pass that will replace Attribute.Placeholders // with Attribute.Compound (made from synthesized containers). ctx.annotateRepeated(new Annotate.Annotator() { - @Override public String toString() { return "repeated annotation pass of: " + sym + " in: " + sym.owner; @@ -150,10 +180,12 @@ } }); } + // Add non-repeating attributes + return buf.reverse(); } public Annotations reset() { - attributes = IN_PROGRESS; + attributes = DECL_IN_PROGRESS; return this; } @@ -163,12 +195,16 @@ || attributes.isEmpty(); } + public boolean isTypesEmpty() { + return type_attributes.isEmpty(); + } + public boolean pendingCompletion() { - return attributes == IN_PROGRESS; + return attributes == DECL_IN_PROGRESS; } public Annotations append(List l) { - attributes = filterSentinels(attributes); + attributes = filterDeclSentinels(attributes); if (l.isEmpty()) { ; // no-op @@ -180,8 +216,24 @@ return this; } + public Annotations appendUniqueTypes(List l) { + if (l.isEmpty()) { + ; // no-op + } else if (type_attributes.isEmpty()) { + type_attributes = l; + } else { + // TODO: in case we expect a large number of annotations, this + // might be inefficient. + for (Attribute.TypeCompound tc : l) { + if (!type_attributes.contains(tc)) + type_attributes = type_attributes.append(tc); + } + } + return this; + } + public Annotations prepend(List l) { - attributes = filterSentinels(attributes); + attributes = filterDeclSentinels(attributes); if (l.isEmpty()) { ; // no-op @@ -193,19 +245,29 @@ return this; } - private List filterSentinels(List a) { - return (a == IN_PROGRESS || a == NOT_STARTED) + private List filterDeclSentinels(List a) { + return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED) ? List.nil() : a; } private boolean isStarted() { - return attributes != NOT_STARTED; + return attributes != DECL_NOT_STARTED; } private List getPlaceholders() { List res = List.nil(); - for (Attribute.Compound a : filterSentinels(attributes)) { + for (Attribute.Compound a : filterDeclSentinels(attributes)) { + if (a instanceof Placeholder) { + res = res.prepend(a); + } + } + return res.reverse(); + } + + private List getTypePlaceholders() { + List res = List.nil(); + for (Attribute.TypeCompound a : type_attributes) { if (a instanceof Placeholder) { res = res.prepend(a); } @@ -216,50 +278,78 @@ /* * Replace Placeholders for repeating annotations with their containers */ - private void complete(Annotate.AnnotateRepeatedContext ctx) { - Assert.check(!pendingCompletion()); + private void complete(Annotate.AnnotateRepeatedContext ctx) { Log log = ctx.log; Env env = ctx.env; JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); try { + // TODO: can we reduce duplication in the following branches? + if (ctx.isTypeCompound) { + Assert.check(!isTypesEmpty()); - if (isEmpty()) { - return; - } + if (isTypesEmpty()) { + return; + } - List result = List.nil(); - for (Attribute.Compound a : getAttributes()) { - if (a instanceof Placeholder) { - Attribute.Compound replacement = replaceOne((Placeholder) a, ctx); + List result = List.nil(); + for (Attribute.TypeCompound a : getTypeAttributes()) { + if (a instanceof Placeholder) { + @SuppressWarnings("unchecked") + Placeholder ph = (Placeholder) a; + Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext()); + + if (null != replacement) { + result = result.prepend(replacement); + } + } else { + result = result.prepend(a); + } + } + + type_attributes = result.reverse(); - if (null != replacement) { - result = result.prepend(replacement); - } - } else { - result = result.prepend(a); + Assert.check(Annotations.this.getTypePlaceholders().isEmpty()); + } else { + Assert.check(!pendingCompletion()); + + if (isEmpty()) { + return; } - } + + List result = List.nil(); + for (Attribute.Compound a : getDeclarationAttributes()) { + if (a instanceof Placeholder) { + @SuppressWarnings("unchecked") + Attribute.Compound replacement = replaceOne((Placeholder) a, ctx); - attributes = result.reverse(); + if (null != replacement) { + result = result.prepend(replacement); + } + } else { + result = result.prepend(a); + } + } - Assert.check(Annotations.this.getPlaceholders().isEmpty()); + attributes = result.reverse(); + + Assert.check(Annotations.this.getPlaceholders().isEmpty()); + } } finally { log.useSource(oldSource); } } - private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) { + private T replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) { Log log = ctx.log; // Process repeated annotations - Attribute.Compound validRepeated = - ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); + T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); if (validRepeated != null) { // Check that the container isn't manually // present along with repeated instances of // its contained annotation. - ListBuffer manualContainer = ctx.annotated.get(validRepeated.type.tsym); + ListBuffer manualContainer = ctx.annotated.get(validRepeated.type.tsym); if (manualContainer != null) { log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", manualContainer.first().type.tsym); @@ -268,16 +358,20 @@ // A null return will delete the Placeholder return validRepeated; - } - private static class Placeholder extends Attribute.Compound { + private static class Placeholder extends Attribute.TypeCompound { + + private final Annotate.AnnotateRepeatedContext ctx; + private final List placeholderFor; + private final Symbol on; - private List placeholderFor; - private Symbol on; - - public Placeholder(List placeholderFor, Symbol on) { - super(Type.noType, List.>nil()); + public Placeholder(Annotate.AnnotateRepeatedContext ctx, List placeholderFor, Symbol on) { + super(on.type, List.>nil(), + ctx.isTypeCompound ? + ((Attribute.TypeCompound)placeholderFor.head).position : + null); + this.ctx = ctx; this.placeholderFor = placeholderFor; this.on = on; } @@ -287,8 +381,12 @@ return ""; } - public List getPlaceholderFor() { + public List getPlaceholderFor() { return placeholderFor; } + + public Annotate.AnnotateRepeatedContext getRepeatedContext() { + return ctx; + } } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -217,6 +217,21 @@ } } + public static class TypeCompound extends Compound { + public TypeAnnotationPosition position; + public TypeCompound(Compound compound, + TypeAnnotationPosition position) { + this(compound.type, compound.values, position); + } + public TypeCompound(Type type, + List> values, + TypeAnnotationPosition position) { + super(type, values); + this.position = position; + } + + } + /** The value for an annotation element of an array type. */ public static class Array extends Attribute { diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Flags.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -233,23 +233,23 @@ public static final long PROPRIETARY = 1L<<38; /** - * Flag that marks a a multi-catch parameter + * Flag that marks a multi-catch parameter. */ public static final long UNION = 1L<<39; /** - * Flag that marks a special kind of bridge methods (the ones that - * come from restricted supertype bounds) + * Flag that marks a special kind of bridge method (the ones that + * come from restricted supertype bounds). */ public static final long OVERRIDE_BRIDGE = 1L<<40; /** - * Flag that marks an 'effectively final' local variable + * Flag that marks an 'effectively final' local variable. */ public static final long EFFECTIVELY_FINAL = 1L<<41; /** - * Flag that marks non-override equivalent methods with the same signature + * Flag that marks non-override equivalent methods with the same signature. */ public static final long CLASH = 1L<<42; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Lint.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -74,7 +74,7 @@ * the given annotations. */ public Lint augment(Annotations annots) { - return augmentor.augment(this, annots.getAttributes()); + return augmentor.augment(this, annots.getDeclarationAttributes()); } /** @@ -82,7 +82,7 @@ * the given annotations and flags. */ public Lint augment(Annotations annots, long flags) { - Lint l = augmentor.augment(this, annots.getAttributes()); + Lint l = augmentor.augment(this, annots.getDeclarationAttributes()); if ((flags & DEPRECATED) != 0) { if (l == this) l = new Lint(this); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Printer.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, 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 @@ -27,7 +27,10 @@ import java.util.Locale; +import javax.lang.model.type.TypeKind; + import com.sun.tools.javac.api.Messages; +import com.sun.tools.javac.code.Type.AnnotatedType; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.util.List; @@ -35,7 +38,6 @@ import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; -import static com.sun.tools.javac.code.TypeTag.ARRAY; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.FORALL; @@ -188,7 +190,7 @@ StringBuilder buf = new StringBuilder(); if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) { buf.append(visit(t.getEnclosingType(), locale)); - buf.append("."); + buf.append('.'); buf.append(className(t, false, locale)); } else { buf.append(className(t, true, locale)); @@ -196,7 +198,7 @@ if (t.getTypeArguments().nonEmpty()) { buf.append('<'); buf.append(visitTypes(t.getTypeArguments(), locale)); - buf.append(">"); + buf.append('>'); } return buf.toString(); } @@ -231,6 +233,17 @@ return visitType(t, locale); } + @Override + 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) + ")"; + } else { + return "({} :: " + visit(t.underlyingType, locale) + ")"; + } + } + public String visitType(Type t, Locale locale) { String s = (t.tsym == null || t.tsym.name == null) ? localize(locale, "compiler.misc.type.none") @@ -296,8 +309,13 @@ args = args.tail; buf.append(','); } - if (args.head.tag == ARRAY) { - buf.append(visit(((ArrayType) args.head).elemtype, locale)); + if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) { + buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale)); + if (args.head.getAnnotations().nonEmpty()) { + buf.append(' '); + buf.append(args.head.getAnnotations()); + buf.append(' '); + } buf.append("..."); } else { buf.append(visit(args.head, locale)); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Source.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -176,9 +176,6 @@ public boolean allowTryWithResources() { return compareTo(JDK1_7) >= 0; } - public boolean allowTypeAnnotations() { - return compareTo(JDK1_7) >= 0; - } public boolean allowBinaryLiterals() { return compareTo(JDK1_7) >= 0; } @@ -215,6 +212,9 @@ public boolean allowEffectivelyFinalInInnerClasses() { return compareTo(JDK1_8) >= 0; } + public boolean allowTypeAnnotations() { + return compareTo(JDK1_8) >= 0; + } public boolean allowRepeatedAnnotations() { return compareTo(JDK1_8) >= 0; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jan 23 13:27:24 2013 -0800 @@ -84,7 +84,15 @@ * method to make sure that the class symbol is loaded. */ public List getRawAttributes() { - return annotations.getAttributes(); + return annotations.getDeclarationAttributes(); + } + + /** An accessor method for the type attributes of this symbol. + * Attributes of class symbols should be accessed through the accessor + * method to make sure that the class symbol is loaded. + */ + public List getRawTypeAttributes() { + return annotations.getTypeAttributes(); } /** Fetch a particular annotation from a symbol. */ @@ -455,6 +463,14 @@ } /** + * TODO: Should there be a {@code + * javax.lang.model.element.Element.getTypeAnnotationMirrors()}. + */ + public final List getTypeAnnotationMirrors() { + return getRawTypeAttributes(); + } + + /** * @deprecated this method should never be used by javac internally. */ @Deprecated @@ -795,6 +811,12 @@ return super.getRawAttributes(); } + @Override + public List getRawTypeAttributes() { + if (completer != null) complete(); + return super.getRawTypeAttributes(); + } + public Type erasure(Types types) { if (erasure_field == null) erasure_field = new ClassType(types.erasure(type.getEnclosingType()), @@ -1387,7 +1409,7 @@ return defaultValue; } - public List getParameters() { + public List getParameters() { return params(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,7 @@ package com.sun.tools.javac.code; -import java.util.EnumSet; -import java.util.Set; - -import static com.sun.tools.javac.code.TargetType.TargetAttribute.*; +import com.sun.tools.javac.util.Assert; /** * Describes the type of program element an extended annotation (or extended @@ -44,178 +41,89 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ +// Code duplicated in com.sun.tools.classfile.TypeAnnotation.TargetType public enum TargetType { - - // - // Some target types are commented out, because Java doesn't permit such - // targets. They are included here to confirm that their omission is - // intentional omission not an accidental omission. - // - - /** For annotations on typecasts. */ - TYPECAST(0x00, IsLocal), - - /** For annotations on a type argument or nested array of a typecast. */ - TYPECAST_GENERIC_OR_ARRAY(0x01, HasLocation, IsLocal), - - /** For annotations on type tests. */ - INSTANCEOF(0x02, IsLocal), - - /** For annotations on a type argument or nested array of a type test. */ - INSTANCEOF_GENERIC_OR_ARRAY(0x03, HasLocation, IsLocal), - - /** For annotations on object creation expressions. */ - NEW(0x04, IsLocal), - - /** - * For annotations on a type argument or nested array of an object creation - * expression. - */ - NEW_GENERIC_OR_ARRAY(0x05, HasLocation, IsLocal), - - - /** For annotations on the method receiver. */ - METHOD_RECEIVER(0x06), - - // invalid location - //@Deprecated METHOD_RECEIVER_GENERIC_OR_ARRAY(0x07, HasLocation), - - /** For annotations on local variables. */ - LOCAL_VARIABLE(0x08, IsLocal), + /** For annotations on a class type parameter declaration. */ + CLASS_TYPE_PARAMETER(0x00), - /** For annotations on a type argument or nested array of a local. */ - LOCAL_VARIABLE_GENERIC_OR_ARRAY(0x09, HasLocation, IsLocal), - - // handled by regular annotations - //@Deprecated METHOD_RETURN(0x0A), - - /** - * For annotations on a type argument or nested array of a method return - * type. - */ - METHOD_RETURN_GENERIC_OR_ARRAY(0x0B, HasLocation), - - // handled by regular annotations - //@Deprecated METHOD_PARAMETER(0x0C), - - /** For annotations on a type argument or nested array of a method parameter. */ - METHOD_PARAMETER_GENERIC_OR_ARRAY(0x0D, HasLocation), - - // handled by regular annotations - //@Deprecated FIELD(0x0E), - - /** For annotations on a type argument or nested array of a field. */ - FIELD_GENERIC_OR_ARRAY(0x0F, HasLocation), - - /** For annotations on a bound of a type parameter of a class. */ - CLASS_TYPE_PARAMETER_BOUND(0x10, HasBound, HasParameter), - - /** - * For annotations on a type argument or nested array of a bound of a type - * parameter of a class. - */ - CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x11, HasBound, HasLocation, HasParameter), - - /** For annotations on a bound of a type parameter of a method. */ - METHOD_TYPE_PARAMETER_BOUND(0x12, HasBound, HasParameter), - - /** - * For annotations on a type argument or nested array of a bound of a type - * parameter of a method. - */ - METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x13, HasBound, HasLocation, HasParameter), + /** For annotations on a method type parameter declaration. */ + METHOD_TYPE_PARAMETER(0x01), /** For annotations on the type of an "extends" or "implements" clause. */ - CLASS_EXTENDS(0x14), + CLASS_EXTENDS(0x10), + + /** For annotations on a bound of a type parameter of a class. */ + CLASS_TYPE_PARAMETER_BOUND(0x11), + + /** For annotations on a bound of a type parameter of a method. */ + METHOD_TYPE_PARAMETER_BOUND(0x12), - /** For annotations on the inner type of an "extends" or "implements" clause. */ - CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation), + /** For annotations on a field. */ + FIELD(0x13), + + /** For annotations on a method return type. */ + METHOD_RETURN(0x14), + + /** For annotations on the method receiver. */ + METHOD_RECEIVER(0x15), + + /** For annotations on a method parameter. */ + METHOD_FORMAL_PARAMETER(0x16), /** For annotations on a throws clause in a method declaration. */ - THROWS(0x16), + THROWS(0x17), - // invalid location - //@Deprecated THROWS_GENERIC_OR_ARRAY(0x17, HasLocation), + /** For annotations on a local variable. */ + LOCAL_VARIABLE(0x40, true), + + /** For annotations on a resource variable. */ + RESOURCE_VARIABLE(0x41, true), - /** For annotations in type arguments of object creation expressions. */ - NEW_TYPE_ARGUMENT(0x18, IsLocal), - NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation, IsLocal), + /** For annotations on an exception parameter. */ + EXCEPTION_PARAMETER(0x42, true), - METHOD_TYPE_ARGUMENT(0x1A, IsLocal), - METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation, IsLocal), + /** For annotations on a typecast. */ + CAST(0x43, true), + + /** For annotations on a type test. */ + INSTANCEOF(0x44, true), - WILDCARD_BOUND(0x1C, HasBound), - WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation), + /** For annotations on an object creation expression. */ + NEW(0x45, true), - CLASS_LITERAL(0x1E, IsLocal), - CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation, IsLocal), + /** For annotations on a type argument of an object creation expression. */ + CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true), - METHOD_TYPE_PARAMETER(0x20, HasParameter), + /** For annotations on a type argument of a method call. */ + METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true), - // invalid location - //@Deprecated METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter), + /** For annotations on a lambda parameter type. */ + LAMBDA_FORMAL_PARAMETER(0x48, true), - CLASS_TYPE_PARAMETER(0x22, HasParameter), + /** For annotations on a method reference. */ + METHOD_REFERENCE(0x49, true), - // invalid location - //@Deprecated CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter), + /** For annotations on a type argument of a method reference. */ + METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true), /** For annotations with an unknown target. */ - UNKNOWN(-1); + UNKNOWN(0xFF); - static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22; + private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92; private final int targetTypeValue; - private final Set flags; + private final boolean isLocal; - TargetType(int targetTypeValue, TargetAttribute... attributes) { - if (targetTypeValue < Byte.MIN_VALUE - || targetTypeValue > Byte.MAX_VALUE) - throw new AssertionError("attribute type value needs to be a byte: " + targetTypeValue); - this.targetTypeValue = (byte)targetTypeValue; - flags = EnumSet.noneOf(TargetAttribute.class); - for (TargetAttribute attr : attributes) - flags.add(attr); - } - - /** - * Returns whether or not this TargetType represents an annotation whose - * target is an inner type of a generic or array type. - * - * @return true if this TargetType represents an annotation on an inner - * type, false otherwise - */ - public boolean hasLocation() { - return flags.contains(HasLocation); + private TargetType(int targetTypeValue) { + this(targetTypeValue, false); } - public TargetType getGenericComplement() { - if (hasLocation()) - return this; - else - return fromTargetTypeValue(targetTypeValue() + 1); - } - - /** - * Returns whether or not this TargetType represents an annotation whose - * target has a parameter index. - * - * @return true if this TargetType has a parameter index, - * false otherwise - */ - public boolean hasParameter() { - return flags.contains(HasParameter); - } - - /** - * Returns whether or not this TargetType represents an annotation whose - * target is a type parameter bound. - * - * @return true if this TargetType represents an type parameter bound - * annotation, false otherwise - */ - public boolean hasBound() { - return flags.contains(HasBound); + private TargetType(int targetTypeValue, boolean isLocal) { + if (targetTypeValue < 0 + || targetTypeValue > 255) + Assert.error("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue)); + this.targetTypeValue = targetTypeValue; + this.isLocal = isLocal; } /** @@ -226,7 +134,7 @@ * member declaration signature tree */ public boolean isLocal() { - return flags.contains(IsLocal); + return isLocal; } public int targetTypeValue() { @@ -239,7 +147,7 @@ targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1]; TargetType[] alltargets = values(); for (TargetType target : alltargets) { - if (target.targetTypeValue >= 0) + if (target.targetTypeValue != UNKNOWN.targetTypeValue) targets[target.targetTypeValue] = target; } for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) { @@ -249,22 +157,18 @@ } public static boolean isValidTargetTypeValue(int tag) { - if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue)) + if (tag == UNKNOWN.targetTypeValue) return true; return (tag >= 0 && tag < targets.length); } public static TargetType fromTargetTypeValue(int tag) { - if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue)) + if (tag == UNKNOWN.targetTypeValue) return UNKNOWN; if (tag < 0 || tag >= targets.length) - throw new IllegalArgumentException("Unknown TargetType: " + tag); + Assert.error("Unknown TargetType: " + tag); return targets[tag]; } - - static enum TargetAttribute { - HasLocation, HasParameter, HasBound, IsLocal; - } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Type.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -31,6 +31,7 @@ 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.*; @@ -87,7 +88,7 @@ */ protected TypeTag tag; - /** The defining class / interface / package / type variable + /** The defining class / interface / package / type variable. */ public TypeSymbol tsym; @@ -166,7 +167,7 @@ /** * Get the representation of this type used for modelling purposes. * By default, this is itself. For ErrorType, a different value - * may be provided, + * may be provided. */ public Type getModelType() { return this; @@ -245,6 +246,14 @@ return this; } + /** + * If this is an annotated type, return the underlying type. + * Otherwise, return the type itself. + */ + public Type unannotatedType() { + return this; + } + /** Return the base types of a list of types. */ public static List baseTypes(List ts) { @@ -339,8 +348,11 @@ args = args.tail; buf.append(','); } - if (args.head.tag == ARRAY) { - buf.append(((ArrayType)args.head).elemtype); + if (args.head.unannotatedType().tag == ARRAY) { + buf.append(((ArrayType)args.head.unannotatedType()).elemtype); + if (args.head.getAnnotations().nonEmpty()) { + buf.append(args.head.getAnnotations()); + } buf.append("..."); } else { buf.append(args.head); @@ -350,10 +362,12 @@ /** Access methods. */ + public List getAnnotations() { return List.nil(); } public List getTypeArguments() { return List.nil(); } - public Type getEnclosingType() { return null; } + public Type getEnclosingType() { return null; } public List getParameterTypes() { return List.nil(); } public Type getReturnType() { return null; } + public Type getReceiverType() { return null; } public List getThrownTypes() { return List.nil(); } public Type getUpperBound() { return null; } public Type getLowerBound() { return null; } @@ -600,7 +614,7 @@ /** The enclosing type of this type. If this is the type of an inner * class, outer_field refers to the type of its enclosing - * instance class, in all other cases it referes to noType. + * instance class, in all other cases it refers to noType. */ private Type outer_field; @@ -974,6 +988,10 @@ public Type restype; public List thrown; + /** The type annotations on the method receiver. + */ + public Type recvtype; + public MethodType(List argtypes, Type restype, List thrown, @@ -1000,6 +1018,7 @@ public List getParameterTypes() { return argtypes; } public Type getReturnType() { return restype; } + public Type getReceiverType() { return recvtype; } public List getThrownTypes() { return thrown; } public boolean isErroneous() { @@ -1028,6 +1047,7 @@ for (List l = argtypes; l.nonEmpty(); l = l.tail) l.head.complete(); restype.complete(); + recvtype.complete(); for (List l = thrown; l.nonEmpty(); l = l.tail) l.head.complete(); } @@ -1112,7 +1132,11 @@ } @Override - public Type getUpperBound() { return bound; } + public Type getUpperBound() { + if ((bound == null || bound.tag == NONE) && this != tsym.type) + bound = tsym.type.getUpperBound(); + return bound; + } int rank_field = -1; @@ -1183,6 +1207,7 @@ public Type getEnclosingType() { return qtype.getEnclosingType(); } public List getParameterTypes() { return qtype.getParameterTypes(); } public Type getReturnType() { return qtype.getReturnType(); } + public Type getReceiverType() { return qtype.getReceiverType(); } public List getThrownTypes() { return qtype.getThrownTypes(); } public List allparams() { return qtype.allparams(); } public Type getUpperBound() { return qtype.getUpperBound(); } @@ -1435,7 +1460,7 @@ } public Type constType(Object constValue) { return this; } - public Type getEnclosingType() { return this; } + public Type getEnclosingType() { return this; } public Type getReturnType() { return this; } public Type asSub(Symbol sym) { return this; } public Type map(Mapping f) { return this; } @@ -1461,11 +1486,165 @@ } } + public static class AnnotatedType extends Type + implements javax.lang.model.type.AnnotatedType { + /** The type annotations on this type. + */ + public List typeAnnotations; + + /** The underlying type that is annotated. + */ + public Type underlyingType; + + public AnnotatedType(Type underlyingType) { + super(underlyingType.tag, underlyingType.tsym); + this.typeAnnotations = List.nil(); + this.underlyingType = underlyingType; + Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED, + "Can't annotate already annotated type: " + underlyingType); + } + + public AnnotatedType(List typeAnnotations, + Type underlyingType) { + super(underlyingType.tag, underlyingType.tsym); + this.typeAnnotations = typeAnnotations; + this.underlyingType = underlyingType; + Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED, + "Can't annotate already annotated type: " + underlyingType + + "; adding: " + typeAnnotations); + } + + @Override + public TypeKind getKind() { + return TypeKind.ANNOTATED; + } + + @Override + public List getAnnotations() { + return typeAnnotations; + } + + @Override + public TypeMirror getUnderlyingType() { + return underlyingType; + } + + @Override + public Type unannotatedType() { + return underlyingType; + } + + @Override + public R accept(Type.Visitor v, S s) { + return v.visitAnnotatedType(this, s); + } + + @Override + public R accept(TypeVisitor v, P p) { + return v.visitAnnotated(this, p); + } + + @Override + public Type map(Mapping f) { + underlyingType.map(f); + return this; + } + + @Override + public Type constType(Object constValue) { return underlyingType.constType(constValue); } + @Override + public Type getEnclosingType() { return underlyingType.getEnclosingType(); } + + @Override + public Type getReturnType() { return underlyingType.getReturnType(); } + @Override + public List getTypeArguments() { return underlyingType.getTypeArguments(); } + @Override + public List getParameterTypes() { return underlyingType.getParameterTypes(); } + @Override + public Type getReceiverType() { return underlyingType.getReceiverType(); } + @Override + public List getThrownTypes() { return underlyingType.getThrownTypes(); } + @Override + public Type getUpperBound() { return underlyingType.getUpperBound(); } + @Override + public Type getLowerBound() { return underlyingType.getLowerBound(); } + + @Override + public boolean isErroneous() { return underlyingType.isErroneous(); } + @Override + public boolean isCompound() { return underlyingType.isCompound(); } + @Override + public boolean isInterface() { return underlyingType.isInterface(); } + @Override + public List allparams() { return underlyingType.allparams(); } + @Override + public boolean isNumeric() { return underlyingType.isNumeric(); } + @Override + public boolean isReference() { return underlyingType.isReference(); } + @Override + public boolean isParameterized() { return underlyingType.isParameterized(); } + @Override + public boolean isRaw() { return underlyingType.isRaw(); } + @Override + public boolean isFinal() { return underlyingType.isFinal(); } + @Override + public boolean isSuperBound() { return underlyingType.isSuperBound(); } + @Override + public boolean isExtendsBound() { return underlyingType.isExtendsBound(); } + @Override + public boolean isUnbound() { return underlyingType.isUnbound(); } + + @Override + public String toString() { + // TODO more logic for arrays, etc. + if (typeAnnotations != null && + !typeAnnotations.isEmpty()) { + return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")"; + } else { + return "({} :: " + underlyingType.toString() +")"; + } + } + + @Override + public boolean contains(Type t) { return underlyingType.contains(t); } + + // TODO: attach annotations? + @Override + public Type withTypeVar(Type t) { return underlyingType.withTypeVar(t); } + + // TODO: attach annotations? + @Override + public TypeSymbol asElement() { return underlyingType.asElement(); } + + // TODO: attach annotations? + @Override + public MethodType asMethodType() { return underlyingType.asMethodType(); } + + @Override + public void complete() { underlyingType.complete(); } + + @Override + public TypeMirror getComponentType() { return ((ArrayType)underlyingType).getComponentType(); } + + // The result is an ArrayType, but only in the model sense, not the Type sense. + public AnnotatedType makeVarargs() { + AnnotatedType atype = new AnnotatedType(((ArrayType)underlyingType).makeVarargs()); + atype.typeAnnotations = this.typeAnnotations; + return atype; + } + + @Override + public TypeMirror getExtendsBound() { return ((WildcardType)underlyingType).getExtendsBound(); } + @Override + public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); } + } + /** * A visitor for types. A visitor is used to implement operations * (or relations) on types. Most common operations on types are * binary relations and this interface is designed for binary - * relations, that is, operations on the form + * relations, that is, operations of the form * Type × S → R. * * @@ -1486,6 +1665,7 @@ R visitForAll(ForAll t, S s); R visitUndetVar(UndetVar t, S s); R visitErrorType(ErrorType t, S s); + R visitAnnotatedType(AnnotatedType t, S s); R visitType(Type t, S s); } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, 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 @@ -25,6 +25,8 @@ package com.sun.tools.javac.code; +import java.util.Iterator; + import com.sun.tools.javac.util.*; /** A type annotation position. @@ -34,12 +36,92 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ +// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position public class TypeAnnotationPosition { + public enum TypePathEntryKind { + ARRAY(0), + INNER_TYPE(1), + WILDCARD(2), + TYPE_ARGUMENT(3); + + public final int tag; + + private TypePathEntryKind(int tag) { + this.tag = tag; + } + } + + public static class TypePathEntry { + /** The fixed number of bytes per TypePathEntry. */ + public static final int bytesPerEntry = 2; + + public final TypePathEntryKind tag; + public final int arg; + + public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY); + public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE); + public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD); + + private TypePathEntry(TypePathEntryKind tag) { + Assert.check(tag == TypePathEntryKind.ARRAY || + tag == TypePathEntryKind.INNER_TYPE || + tag == TypePathEntryKind.WILDCARD, + "Invalid TypePathEntryKind: " + tag); + this.tag = tag; + this.arg = 0; + } + + public TypePathEntry(TypePathEntryKind tag, int arg) { + Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT, + "Invalid TypePathEntryKind: " + tag); + this.tag = tag; + this.arg = arg; + } + + public static TypePathEntry fromBinary(int tag, int arg) { + Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag, + "Invalid TypePathEntry tag/arg: " + tag + "/" + arg); + switch (tag) { + case 0: + return ARRAY; + case 1: + return INNER_TYPE; + case 2: + return WILDCARD; + case 3: + return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg); + default: + Assert.error("Invalid TypePathEntryKind tag: " + tag); + return null; + } + } + + @Override + public String toString() { + return tag.toString() + + (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : ""); + } + + @Override + public boolean equals(Object other) { + if (! (other instanceof TypePathEntry)) { + return false; + } + TypePathEntry tpe = (TypePathEntry) other; + return this.tag == tpe.tag && this.arg == tpe.arg; + } + + @Override + public int hashCode() { + return this.tag.hashCode() * 17 + this.arg; + } + } + public TargetType type = TargetType.UNKNOWN; // For generic/array types. - public List location = List.nil(); + public List location = List.nil(); // Tree position. public int pos = -1; @@ -59,11 +141,13 @@ // For type parameter and method parameter public int parameter_index = Integer.MIN_VALUE; - // For class extends, implements, and throws classes + // For class extends, implements, and throws clauses public int type_index = Integer.MIN_VALUE; - // For wildcards - public TypeAnnotationPosition wildcard_position = null; + // For exception parameters, index into exception table + public int exception_index = Integer.MIN_VALUE; + + public TypeAnnotationPosition() {} @Override public String toString() { @@ -72,27 +156,27 @@ sb.append(type); switch (type) { - // type case - case TYPECAST: - case TYPECAST_GENERIC_OR_ARRAY: - // object creation + // type cast + case CAST: + // instanceof case INSTANCEOF: - case INSTANCEOF_GENERIC_OR_ARRAY: - // new expression + // new expression case NEW: - case NEW_GENERIC_OR_ARRAY: - case NEW_TYPE_ARGUMENT: - case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY: sb.append(", offset = "); sb.append(offset); break; - // local variable + // local variable case LOCAL_VARIABLE: - case LOCAL_VARIABLE_GENERIC_OR_ARRAY: + // resource variable + case RESOURCE_VARIABLE: + if (lvarOffset == null) { + sb.append(", lvarOffset is null!"); + break; + } sb.append(", {"); for (int i = 0; i < lvarOffset.length; ++i) { if (i != 0) sb.append("; "); - sb.append(", start_pc = "); + sb.append("start_pc = "); sb.append(lvarOffset[i]); sb.append(", length = "); sb.append(lvarLength[i]); @@ -101,73 +185,72 @@ } sb.append("}"); break; - // method receiver + // method receiver case METHOD_RECEIVER: // Do nothing break; - // type parameters + // type parameter case CLASS_TYPE_PARAMETER: case METHOD_TYPE_PARAMETER: sb.append(", param_index = "); sb.append(parameter_index); break; - // type parameters bound + // type parameter bound case CLASS_TYPE_PARAMETER_BOUND: - case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: case METHOD_TYPE_PARAMETER_BOUND: - case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: sb.append(", param_index = "); sb.append(parameter_index); sb.append(", bound_index = "); sb.append(bound_index); break; - // wildcard - case WILDCARD_BOUND: - case WILDCARD_BOUND_GENERIC_OR_ARRAY: - sb.append(", wild_card = "); - sb.append(wildcard_position); - break; - // Class extends and implements clauses + // class extends or implements clause case CLASS_EXTENDS: - case CLASS_EXTENDS_GENERIC_OR_ARRAY: sb.append(", type_index = "); sb.append(type_index); break; - // throws + // throws case THROWS: sb.append(", type_index = "); sb.append(type_index); break; - case CLASS_LITERAL: - case CLASS_LITERAL_GENERIC_OR_ARRAY: - sb.append(", offset = "); - sb.append(offset); + // exception parameter + case EXCEPTION_PARAMETER: + sb.append(", exception_index = "); + sb.append(exception_index); break; - // method parameter: not specified - case METHOD_PARAMETER_GENERIC_OR_ARRAY: + // method parameter + case METHOD_FORMAL_PARAMETER: sb.append(", param_index = "); sb.append(parameter_index); break; - // method type argument: wasn't specified - case METHOD_TYPE_ARGUMENT: - case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY: + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: sb.append(", offset = "); sb.append(offset); sb.append(", type_index = "); sb.append(type_index); break; - // We don't need to worry abut these - case METHOD_RETURN_GENERIC_OR_ARRAY: - case FIELD_GENERIC_OR_ARRAY: + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + // TODO: also needs an offset? + sb.append(", param_index = "); + sb.append(parameter_index); break; case UNKNOWN: + sb.append(", position UNKNOWN!"); break; default: - // throw new AssertionError("unknown type: " + type); + Assert.error("Unknown target type: " + type); } // Append location data for generics/arrays. - if (type.hasLocation()) { + if (!location.isEmpty()) { sb.append(", location = ("); sb.append(location); sb.append(")"); @@ -186,10 +269,33 @@ * @return true if the target has not been optimized away */ public boolean emitToClassfile() { - if (type == TargetType.WILDCARD_BOUND - || type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY) - return wildcard_position.isValidOffset; - else - return !type.isLocal() || isValidOffset; + return !type.isLocal() || isValidOffset; + } + + /** + * Decode the binary representation for a type path and set + * the {@code location} field. + * + * @param list The bytecode representation of the type path. + */ + public static List getTypePathFromBinary(java.util.List list) { + ListBuffer loc = ListBuffer.lb(); + Iterator iter = list.iterator(); + while (iter.hasNext()) { + Integer fst = iter.next(); + Assert.check(iter.hasNext(), "Could not decode type path: " + list); + Integer snd = iter.next(); + loc = loc.append(TypePathEntry.fromBinary(fst, snd)); + } + return loc.toList(); + } + + public static List getBinaryFromTypePath(java.util.List locs) { + ListBuffer loc = ListBuffer.lb(); + for (TypePathEntry tpe : locs) { + loc = loc.append(tpe.tag.tag); + loc = loc.append(tpe.arg); + } + return loc.toList(); } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,1037 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.code; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.type.TypeKind; + +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Kinds; +import com.sun.tools.javac.code.Type.AnnotatedType; +import com.sun.tools.javac.code.Type.ArrayType; +import com.sun.tools.javac.code.Type.CapturedType; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.Type.ErrorType; +import com.sun.tools.javac.code.Type.ForAll; +import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.code.Type.PackageType; +import com.sun.tools.javac.code.Type.TypeVar; +import com.sun.tools.javac.code.Type.UndetVar; +import com.sun.tools.javac.code.Type.Visitor; +import com.sun.tools.javac.code.Type.WildcardType; +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; +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.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.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; + +/** + * Contains operations specific to processing type annotations. + * This class has two functions: + * separate declaration from type annotations and insert the type + * annotations to their types; + * and determine the TypeAnnotationPositions for all type annotations. + */ +public class TypeAnnotations { + // Class cannot be instantiated. + private TypeAnnotations() {} + + /** + * Separate type annotations from declaration annotations and + * 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. + */ + public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, + final Log log, final JCClassDecl tree) { + return new Annotator() { + @Override + public void enterAnnotation() { + new TypeAnnotationPositions(syms, names, log, true).scan(tree); + } + }; + } + + /** + * This version only visits types in bodies, that is, field initializers, + * top-level blocks, and method bodies, and should be called from Attr. + */ + public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) { + new TypeAnnotationPositions(syms, names, log, false).scan(tree); + } + + private static class TypeAnnotationPositions extends TreeScanner { + + private enum AnnotationType { DECLARATION, TYPE, BOTH }; + + private final Symtab syms; + private final Names names; + private final Log log; + private final boolean sigOnly; + + private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) { + this.syms = syms; + this.names = names; + this.log = log; + this.sigOnly = sigOnly; + } + + /* + * When traversing the AST we keep the "frames" of visited + * trees in order to determine the position of annotations. + */ + private ListBuffer frames = ListBuffer.lb(); + + protected void push(JCTree t) { frames = frames.prepend(t); } + protected JCTree pop() { return frames.next(); } + // could this be frames.elems.tail.head? + private JCTree peek2() { return frames.toList().tail.head; } + + @Override + public void scan(JCTree tree) { + push(tree); + super.scan(tree); + pop(); + } + + /** + * Separates type annotations from declaration annotations. + * This step is needed because in certain locations (where declaration + * and type annotations can be mixed, e.g. the type of a field) + * we never build an JCAnnotatedType. This step finds these + * annotations and marks them as if they were part of the type. + */ + private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym, + TypeAnnotationPosition pos) { + /* + System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n", + typetree, type, sym, pos); + */ + List annotations = sym.getRawAttributes(); + ListBuffer declAnnos = new ListBuffer(); + ListBuffer typeAnnos = new ListBuffer(); + + for (Attribute.Compound a : annotations) { + switch (annotationType(a, sym)) { + case DECLARATION: + declAnnos.append(a); + break; + case BOTH: { + declAnnos.append(a); + Attribute.TypeCompound ta = toTypeCompound(a, pos); + typeAnnos.append(ta); + break; + } + case TYPE: { + Attribute.TypeCompound ta = toTypeCompound(a, pos); + typeAnnos.append(ta); + break; + } + } + } + + sym.annotations.reset(); + sym.annotations.setDeclarationAttributes(declAnnos.toList()); + + List typeAnnotations = typeAnnos.toList(); + + if (type == null) { + // When type is null, put the type annotations to the symbol. + // This is used for constructor return annotations, for which + // no appropriate type exists. + sym.annotations.appendUniqueTypes(typeAnnotations); + return; + } + + // type is non-null and annotations are added to that type + type = typeWithAnnotations(typetree, type, typeAnnotations, log); + + if (sym.getKind() == ElementKind.METHOD) { + sym.type.asMethodType().restype = type; + } 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 || + sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { + // Make sure all type annotations from the symbol are also + // on the owner. + sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors()); + } + } + + // This method has a similar purpose as + // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List, boolean)} + // We found a type annotation in a declaration annotation position, + // for example, on the return type. + // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore + // need to set its position explicitly. + // The method returns a copy of type that contains these annotations. + private static Type typeWithAnnotations(final JCTree typetree, final Type type, + final List annotations, Log log) { + // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", + // typetree, type, annotations); + if (annotations.isEmpty()) { + return type; + } + if (type.hasTag(TypeTag.ARRAY)) { + Type toreturn; + Type.ArrayType tomodify; + Type.ArrayType arType; + { + Type touse = type; + if (type.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType atype = (Type.AnnotatedType)type; + toreturn = new Type.AnnotatedType(atype.underlyingType); + ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations; + touse = atype.underlyingType; + arType = (Type.ArrayType) touse; + tomodify = new Type.ArrayType(null, arType.tsym); + ((Type.AnnotatedType)toreturn).underlyingType = tomodify; + } else { + arType = (Type.ArrayType) touse; + tomodify = new Type.ArrayType(null, arType.tsym); + toreturn = tomodify; + } + } + JCArrayTypeTree arTree = arrayTypeTree(typetree); + + ListBuffer depth = ListBuffer.lb(); + depth = depth.append(TypePathEntry.ARRAY); + while (arType.elemtype.hasTag(TypeTag.ARRAY)) { + if (arType.elemtype.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype; + Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType); + tomodify.elemtype = newAT; + newAT.typeAnnotations = aelemtype.typeAnnotations; + arType = (Type.ArrayType) aelemtype.underlyingType; + tomodify = new Type.ArrayType(null, arType.tsym); + newAT.underlyingType = tomodify; + } else { + arType = (Type.ArrayType) arType.elemtype; + tomodify.elemtype = new Type.ArrayType(null, arType.tsym); + tomodify = (Type.ArrayType) tomodify.elemtype; + } + arTree = arrayTypeTree(arTree.elemtype); + depth = depth.append(TypePathEntry.ARRAY); + } + Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log); + tomodify.elemtype = arelemType; + for (Attribute.TypeCompound a : annotations) { + TypeAnnotationPosition p = a.position; + p.location = p.location.prependList(depth.toList()); + } + return toreturn; + } else if (type.hasTag(TypeTag.TYPEVAR)) { + // Nothing to do for type variables. + return type; + } else { + Type enclTy = type; + Element enclEl = type.asElement(); + JCTree enclTr = typetree; + + while (enclEl != null && + enclEl.getKind() != ElementKind.PACKAGE && + enclTy != null && + enclTy.getKind() != TypeKind.NONE && + enclTy.getKind() != TypeKind.ERROR && + (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { + // Iterate also over the type tree, not just the type: the type is already + // completely resolved and we cannot distinguish where the annotation + // belongs for a nested type. + if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) { + // only change encl in this case. + enclTy = enclTy.getEnclosingType(); + enclEl = enclEl.getEnclosingElement(); + enclTr = ((JCFieldAccess)enclTr).getExpression(); + } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) { + enclTr = ((JCTypeApply)enclTr).getType(); + } else { + // only other option because of while condition + enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType(); + } + } + + /** We are trying to annotate some enclosing type, + * but nothing more exists. + */ + if (enclTy != null && + enclTy.getKind() == TypeKind.NONE && + (enclTr.getKind() == JCTree.Kind.IDENTIFIER || + enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { + // TODO: also if it's "java. @A lang.Object", that is, + // if it's on a package? + log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString()); + return type; + } + + // At this point we have visited the part of the nested + // type that is written in the source code. + // Now count from here to the actual top-level class to determine + // the correct nesting. + + // The genericLocation for the annotation. + ListBuffer depth = ListBuffer.lb(); + + Type topTy = enclTy; + while (enclEl != null && + enclEl.getKind() != ElementKind.PACKAGE && + topTy != null && + topTy.getKind() != TypeKind.NONE && + topTy.getKind() != TypeKind.ERROR) { + topTy = topTy.getEnclosingType(); + enclEl = enclEl.getEnclosingElement(); + + if (topTy != null && topTy.getKind() != TypeKind.NONE) { + // Only count enclosing types. + depth = depth.append(TypePathEntry.INNER_TYPE); + } + } + + if (depth.nonEmpty()) { + // Only need to change the annotation positions + // if they are on an enclosed type. + for (Attribute.TypeCompound a : annotations) { + TypeAnnotationPosition p = a.position; + p.location = p.location.appendList(depth.toList()); + } + } + + Type ret = typeWithAnnotations(type, enclTy, annotations); + return ret; + } + } + + private static JCArrayTypeTree arrayTypeTree(JCTree typetree) { + if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { + return (JCArrayTypeTree) typetree; + } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { + return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType; + } else { + Assert.error("Could not determine array type from type tree: " + typetree); + return null; + } + } + + /** Return a copy of the first type that only differs by + * inserting the annotations to the left-most/inner-most type + * or the type given by stopAt. + * + * We need the stopAt parameter to know where on a type to + * put the annotations. + * If we have nested classes Outer > Middle > Inner, and we + * have the source type "@A Middle.Inner", we will invoke + * this method with type = Outer.Middle.Inner, + * stopAt = Middle.Inner, and annotations = @A. + * + * @param type The type to copy. + * @param stopAt The type to stop at. + * @param annotations The annotations to insert. + * @return A copy of type that contains the annotations. + */ + private static Type typeWithAnnotations(final Type type, + final Type stopAt, + final List annotations) { + Visitor> visitor = + new Type.Visitor>() { + @Override + public Type visitClassType(ClassType t, List s) { + // assert that t.constValue() == null? + if (t == stopAt || + t.getEnclosingType() == Type.noType) { + return new AnnotatedType(s, t); + } else { + ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), + t.typarams_field, t.tsym); + ret.all_interfaces_field = t.all_interfaces_field; + ret.allparams_field = t.allparams_field; + ret.interfaces_field = t.interfaces_field; + ret.rank_field = t.rank_field; + ret.supertype_field = t.supertype_field; + return ret; + } + } + + @Override + public Type visitAnnotatedType(AnnotatedType t, List s) { + return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s)); + } + + @Override + public Type visitWildcardType(WildcardType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitArrayType(ArrayType t, List s) { + ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym); + return ret; + } + + @Override + public Type visitMethodType(MethodType t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitPackageType(PackageType t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitTypeVar(TypeVar t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitCapturedType(CapturedType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitForAll(ForAll t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitUndetVar(UndetVar t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitErrorType(ErrorType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitType(Type t, List s) { + // Error? + return t; + } + }; + + return type.accept(visitor, annotations); + } + + private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { + // It is safe to alias the position. + 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. + */ + + private void resolveFrame(JCTree tree, JCTree frame, + List path, TypeAnnotationPosition p) { + /* + System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind()); + System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind()); + */ + switch (frame.getKind()) { + case TYPE_CAST: + p.type = TargetType.CAST; + p.pos = frame.pos; + return; + + case INSTANCE_OF: + p.type = TargetType.INSTANCEOF; + p.pos = frame.pos; + return; + + case NEW_CLASS: + JCNewClass frameNewClass = (JCNewClass)frame; + if (frameNewClass.typeargs.contains(tree)) { + p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; + p.type_index = frameNewClass.typeargs.indexOf(tree); + } else { + p.type = TargetType.NEW; + } + p.pos = frame.pos; + return; + + case NEW_ARRAY: + p.type = TargetType.NEW; + p.pos = frame.pos; + return; + + case ANNOTATION_TYPE: + case CLASS: + case ENUM: + case INTERFACE: + p.pos = frame.pos; + if (((JCClassDecl)frame).extending == tree) { + p.type = TargetType.CLASS_EXTENDS; + p.type_index = -1; + } else if (((JCClassDecl)frame).implementing.contains(tree)) { + p.type = TargetType.CLASS_EXTENDS; + p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree); + } else if (((JCClassDecl)frame).typarams.contains(tree)) { + p.type = TargetType.CLASS_TYPE_PARAMETER; + p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree); + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + return; + + case METHOD: { + JCMethodDecl frameMethod = (JCMethodDecl) frame; + p.pos = frame.pos; + if (frameMethod.thrown.contains(tree)) { + p.type = TargetType.THROWS; + p.type_index = frameMethod.thrown.indexOf(tree); + } else if (frameMethod.restype == tree) { + p.type = TargetType.METHOD_RETURN; + } else if (frameMethod.typarams.contains(tree)) { + p.type = TargetType.METHOD_TYPE_PARAMETER; + p.parameter_index = frameMethod.typarams.indexOf(tree); + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + return; + } + + case PARAMETERIZED_TYPE: { + if (((JCTypeApply)frame).clazz == tree) { + // generic: RAW; noop + } else if (((JCTypeApply)frame).arguments.contains(tree)) { + JCTypeApply taframe = (JCTypeApply) frame; + int arg = taframe.arguments.indexOf(tree); + p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg)); + + locateNestedTypes(taframe.type, p); + } else { + Assert.error("Could not determine type argument position of tree " + tree + + " within frame " + frame); + } + + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case ARRAY_TYPE: { + ListBuffer index = ListBuffer.lb(); + index = index.append(TypePathEntry.ARRAY); + List newPath = path.tail; + while (true) { + JCTree npHead = newPath.tail.head; + if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) { + newPath = newPath.tail; + index = index.append(TypePathEntry.ARRAY); + } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { + newPath = newPath.tail; + } else { + break; + } + } + p.location = p.location.prependList(index.toList()); + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case TYPE_PARAMETER: + if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) { + JCClassDecl clazz = (JCClassDecl)path.tail.tail.head; + p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND; + p.parameter_index = clazz.typarams.indexOf(path.tail.head); + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { + // Account for an implicit Object as bound 0 + p.bound_index += 1; + } + } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) { + JCMethodDecl method = (JCMethodDecl)path.tail.tail.head; + p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND; + p.parameter_index = method.typarams.indexOf(path.tail.head); + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { + // Account for an implicit Object as bound 0 + p.bound_index += 1; + } + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + p.pos = frame.pos; + return; + + case VARIABLE: + VarSymbol v = ((JCVariableDecl)frame).sym; + p.pos = frame.pos; + switch (v.getKind()) { + case LOCAL_VARIABLE: + p.type = TargetType.LOCAL_VARIABLE; + break; + case FIELD: + p.type = TargetType.FIELD; + break; + case PARAMETER: + if (v.getQualifiedName().equals(names._this)) { + // TODO: Intro a separate ElementKind? + p.type = TargetType.METHOD_RECEIVER; + } else { + p.type = TargetType.METHOD_FORMAL_PARAMETER; + p.parameter_index = methodParamIndex(path, frame); + } + break; + case EXCEPTION_PARAMETER: + p.type = TargetType.EXCEPTION_PARAMETER; + break; + case RESOURCE_VARIABLE: + p.type = TargetType.RESOURCE_VARIABLE; + break; + default: + Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind()); + } + return; + + case ANNOTATED_TYPE: { + if (frame == tree) { + // This is only true for the first annotated type we see. + // For any other annotated types along the path, we do + // not care about inner types. + JCAnnotatedType atypetree = (JCAnnotatedType) frame; + final Type utype = atypetree.underlyingType.type; + Symbol tsym = utype.tsym; + if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) || + utype.getKind().equals(TypeKind.WILDCARD) || + utype.getKind().equals(TypeKind.ARRAY)) { + // Type parameters, wildcards, and arrays have the declaring + // class/method as enclosing elements. + // There is actually nothing to do for them. + } else { + locateNestedTypes(utype, p); + } + } + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case UNION_TYPE: { + // TODO: can we store any information here to help in + // determining the final position? + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case METHOD_INVOCATION: { + JCMethodInvocation invocation = (JCMethodInvocation)frame; + if (!invocation.typeargs.contains(tree)) { + Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation); + } + p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; + p.pos = invocation.pos; + p.type_index = invocation.typeargs.indexOf(tree); + return; + } + + case EXTENDS_WILDCARD: + case SUPER_WILDCARD: { + // Annotations in wildcard bounds + p.location = p.location.prepend(TypePathEntry.WILDCARD); + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case MEMBER_SELECT: { + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + default: + Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() + + "\n Looking for tree: " + tree); + return; + } + } + + private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { + // The number of "steps" to get from the full type to the + // left-most outer type. + ListBuffer depth = ListBuffer.lb(); + + Type encl = type.getEnclosingType(); + while (encl != null && + encl.getKind() != TypeKind.NONE && + encl.getKind() != TypeKind.ERROR) { + depth = depth.append(TypePathEntry.INNER_TYPE); + encl = encl.getEnclosingType(); + } + if (depth.nonEmpty()) { + p.location = p.location.prependList(depth.toList()); + } + } + + private static int methodParamIndex(List path, JCTree param) { + List curr = path; + while (curr.head.getTag() != Tag.METHODDEF) { + curr = curr.tail; + } + JCMethodDecl method = (JCMethodDecl)curr.head; + return method.params.indexOf(param); + } + + // Each class (including enclosed inner classes) is visited separately. + // This flag is used to prevent from visiting inner classes. + private boolean isInClass = false; + + @Override + public void visitClassDef(JCClassDecl tree) { + if (isInClass) + return; + isInClass = true; + if (sigOnly) { + scan(tree.mods); + scan(tree.typarams); + scan(tree.extending); + scan(tree.implementing); + } + scan(tree.defs); + } + + /** + * Resolve declaration vs. type annotations in methods and + * then determine the positions. + */ + @Override + public void visitMethodDef(final JCMethodDecl tree) { + if (tree.sym == null) { + // Something most be wrong, e.g. a class not found. + // Quietly ignore. (See test FailOver15.java) + return; + } + if (sigOnly) { + { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.METHOD_RETURN; + if (tree.sym.isConstructor()) { + pos.pos = tree.pos; + // Use null to mark that the annotations go with the symbol. + separateAnnotationsKinds(tree, null, tree.sym, pos); + } else { + pos.pos = tree.restype.pos; + separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(), + tree.sym, pos); + } + } + if (tree.recvparam != null && tree.recvparam.sym != null) { + // TODO: make sure there are no declaration annotations. + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.METHOD_RECEIVER; + pos.pos = tree.recvparam.vartype.pos; + separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type, + tree.recvparam.sym, pos); + } + 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); + ++i; + } + } + + push(tree); + // super.visitMethodDef(tree); + if (sigOnly) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + } else { + scan(tree.defaultValue); + scan(tree.body); + } + pop(); + } + + /** + * Resolve declaration vs. type annotations in variable declarations and + * then determine the positions. + */ + @Override + public void visitVarDef(final JCVariableDecl tree) { + if (tree.sym == null) { + // Something is wrong already. Quietly ignore. + } else if (tree.sym.getKind() == ElementKind.FIELD) { + if (sigOnly) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.FIELD; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } + } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.LOCAL_VARIABLE; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { + // System.out.println("Found exception param: " + tree); + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.EXCEPTION_PARAMETER; + pos.pos = tree.pos; + 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; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } else { + // There is nothing else in a variable declaration that needs separation. + // System.out.println("We found a: " + tree); + } + + push(tree); + // super.visitVarDef(tree); + scan(tree.mods); + scan(tree.vartype); + if (!sigOnly) { + scan(tree.init); + } + pop(); + } + + @Override + public void visitBlock(JCBlock tree) { + // Do not descend into top-level blocks when only interested + // in the signature. + if (!sigOnly) { + scan(tree.stats); + } + } + + @Override + public void visitAnnotatedType(JCAnnotatedType tree) { + push(tree); + findPosition(tree, tree, tree.annotations); + pop(); + super.visitAnnotatedType(tree); + } + + @Override + public void visitTypeParameter(JCTypeParameter tree) { + findPosition(tree, peek2(), tree.annotations); + super.visitTypeParameter(tree); + } + + @Override + public void visitNewArray(JCNewArray tree) { + findPosition(tree, tree, tree.annotations); + int dimAnnosCount = tree.dimAnnotations.size(); + ListBuffer depth = ListBuffer.lb(); + + // handle annotations associated with dimensions + for (int i = 0; i < dimAnnosCount; ++i) { + TypeAnnotationPosition p = new TypeAnnotationPosition(); + p.pos = tree.pos; + p.type = TargetType.NEW; + if (i != 0) { + depth = depth.append(TypePathEntry.ARRAY); + p.location = p.location.appendList(depth.toList()); + } + + setTypeAnnotationPos(tree.dimAnnotations.get(i), p); + } + + // handle "free" annotations + // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; + // TODO: is depth.size == i here? + JCExpression elemType = tree.elemtype; + 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()); + setTypeAnnotationPos(at.annotations, p); + elemType = at.underlyingType; + } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) { + depth = depth.append(TypePathEntry.ARRAY); + elemType = ((JCArrayTypeTree)elemType).elemtype; + } else { + break; + } + } + scan(tree.elems); + } + + private void findPosition(JCTree tree, JCTree frame, List annotations) { + if (!annotations.isEmpty()) { + /* + System.out.println("Finding pos for: " + annotations); + System.out.println(" tree: " + tree); + System.out.println(" frame: " + frame); + */ + TypeAnnotationPosition p = new TypeAnnotationPosition(); + resolveFrame(tree, frame, frames.toList(), p); + setTypeAnnotationPos(annotations, p); + } + } + + private static void setTypeAnnotationPos(List annotations, + TypeAnnotationPosition position) { + for (JCAnnotation anno : annotations) { + ((Attribute.TypeCompound) anno.attribute).position = position; + } + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -34,13 +34,14 @@ 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; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.util.*; -import com.sun.tools.javac.util.List; import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Scope.*; @@ -684,6 +685,8 @@ //where private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { + t = t.unannotatedType(); + s = s.unannotatedType(); if (((ArrayType)t).elemtype.isPrimitive()) { return isSameType(elemtype(t), elemtype(s)); } else { @@ -709,7 +712,10 @@ } private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { - if (t.tag != ARRAY || isReifiable(t)) return; + if (t.tag != ARRAY || isReifiable(t)) + return; + t = t.unannotatedType(); + s = s.unannotatedType(); ArrayType from = (ArrayType)t; boolean shouldWarn = false; switch (s.tag) { @@ -742,6 +748,12 @@ if (t == s) return true; + t = t.unannotatedType(); + s = s.unannotatedType(); + + if (t == s) + return true; + if (s.isPartial()) return isSuperType(s, t); @@ -1683,6 +1695,7 @@ case WILDCARD: return elemtype(upperBound(t)); case ARRAY: + t = t.unannotatedType(); return ((ArrayType)t).elemtype; case FORALL: return elemtype(((ForAll)t).qtype); @@ -2011,6 +2024,11 @@ public Type visitErrorType(ErrorType t, Boolean recurse) { return t; } + + @Override + public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { + return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse)); + } }; private Mapping erasureFun = new Mapping ("erasure") { @@ -2953,6 +2971,7 @@ * graph. Undefined for all but reference types. */ public int rank(Type t) { + t = t.unannotatedType(); switch(t.tag) { case CLASS: { ClassType cls = (ClassType)t; @@ -3654,6 +3673,7 @@ t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); } } + t = t.unannotatedType(); ClassType cls = (ClassType)t; if (cls.isRaw() || !cls.isParameterized()) return cls; @@ -4172,6 +4192,8 @@ public R visitForAll(ForAll t, S s) { return visitType(t, s); } public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } + // Pretend annotations don't exist + public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); } } /** diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jan 23 13:27:24 2013 -0800 @@ -26,6 +26,7 @@ package com.sun.tools.javac.comp; import java.util.Map; + import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.*; @@ -87,20 +88,30 @@ private int enterCount = 0; ListBuffer q = new ListBuffer(); + ListBuffer typesQ = new ListBuffer(); ListBuffer repeatedQ = new ListBuffer(); + ListBuffer afterRepeatedQ = new ListBuffer(); + + public void earlier(Annotator a) { + q.prepend(a); + } public void normal(Annotator a) { q.append(a); } - public void earlier(Annotator a) { - q.prepend(a); + public void typeAnnotation(Annotator a) { + typesQ.append(a); } public void repeated(Annotator a) { repeatedQ.append(a); } + public void afterRepeated(Annotator a) { + afterRepeatedQ.append(a); + } + /** Called when the Enter phase starts. */ public void enterStart() { enterCount++; @@ -116,12 +127,18 @@ if (enterCount != 0) return; enterCount++; try { - while (q.nonEmpty()) + while (q.nonEmpty()) { q.next().enterAnnotation(); - + } + while (typesQ.nonEmpty()) { + typesQ.next().enterAnnotation(); + } while (repeatedQ.nonEmpty()) { repeatedQ.next().enterAnnotation(); } + while (afterRepeatedQ.nonEmpty()) { + afterRepeatedQ.next().enterAnnotation(); + } } finally { enterCount--; } @@ -141,16 +158,18 @@ * This context contains all the information needed to synthesize new * annotations trees by the completer for repeating annotations. */ - public class AnnotateRepeatedContext { + public class AnnotateRepeatedContext { public final Env env; - public final Map> annotated; - public final Map pos; + public final Map> annotated; + public final Map pos; public final Log log; + public final boolean isTypeCompound; public AnnotateRepeatedContext(Env env, - Map> annotated, - Map pos, - Log log) { + Map> annotated, + Map pos, + Log log, + boolean isTypeCompound) { Assert.checkNonNull(env); Assert.checkNonNull(annotated); Assert.checkNonNull(pos); @@ -160,6 +179,7 @@ this.annotated = annotated; this.pos = pos; this.log = log; + this.isTypeCompound = isTypeCompound; } /** @@ -170,7 +190,7 @@ * @param repeatingAnnotations a List of repeating annotations * @return a new Attribute.Compound that is the container for the repeatingAnnotations */ - public Attribute.Compound processRepeatedAnnotations(List repeatingAnnotations, Symbol sym) { + public T processRepeatedAnnotations(List repeatingAnnotations, Symbol sym) { return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this, sym); } @@ -246,7 +266,12 @@ ((MethodSymbol)method, value)); t.type = result; } - return new Attribute.Compound(a.type, buf.toList()); + // 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; } Attribute enterAttributeValue(Type expected, @@ -329,6 +354,15 @@ return new Attribute.Error(attr.attribExpr(tree, env, expected)); } + Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a, + Type expected, + Env 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 ***********************************/ @@ -337,10 +371,10 @@ * synthesized container annotation or null IFF all repeating * annotation are invalid. This method reports errors/warnings. */ - private Attribute.Compound processRepeatedAnnotations(List annotations, - AnnotateRepeatedContext ctx, - Symbol on) { - Attribute.Compound firstOccurrence = annotations.head; + private T processRepeatedAnnotations(List annotations, + AnnotateRepeatedContext ctx, + Symbol on) { + T firstOccurrence = annotations.head; List repeated = List.nil(); Type origAnnoType = null; Type arrayOfOrigAnnoType = null; @@ -350,16 +384,16 @@ Assert.check(!annotations.isEmpty() && !annotations.tail.isEmpty()); // i.e. size() > 1 - for (List al = annotations; + for (List al = annotations; !al.isEmpty(); al = al.tail) { - Attribute.Compound currentAnno = al.head; + T currentAnno = al.head; origAnnoType = currentAnno.type; if (arrayOfOrigAnnoType == null) { arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); -} + } Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno)); if (currentContainerType == null) { @@ -383,25 +417,46 @@ if (!repeated.isEmpty()) { repeated = repeated.reverse(); - JCAnnotation annoTree; TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); Pair p = new Pair(containerValueSymbol, new Attribute.Array(arrayOfOrigAnnoType, repeated)); - annoTree = m.Annotation(new Attribute.Compound(targetContainerType, - List.of(p))); + if (ctx.isTypeCompound) { + /* TODO: the following code would be cleaner: + Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), + ((Attribute.TypeCompound)annotations.head).position); + JCTypeAnnotation annoTree = m.TypeAnnotation(at); + at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env); + */ + // However, we directly construct the TypeCompound to keep the + // direct relation to the contained TypeCompounds. + Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), + ((Attribute.TypeCompound)annotations.head).position); - if (!chk.annotationApplicable(annoTree, on)) - log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); + // TODO: annotation applicability checks from below? + + at.setSynthesized(true); - if (!chk.validateAnnotationDeferErrors(annoTree)) - log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); + @SuppressWarnings("unchecked") + T x = (T) at; + return x; + } else { + Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p)); + JCAnnotation annoTree = m.Annotation(c); + + if (!chk.annotationApplicable(annoTree, on)) + log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); - Attribute.Compound c = enterAnnotation(annoTree, - targetContainerType, - ctx.env); - c.setSynthesized(true); - return c; + if (!chk.validateAnnotationDeferErrors(annoTree)) + log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); + + c = enterAnnotation(annoTree, targetContainerType, ctx.env); + c.setSynthesized(true); + + @SuppressWarnings("unchecked") + T x = (T) c; + return x; + } } else { return null; // errors should have been reported elsewhere } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jan 23 13:27:24 2013 -0800 @@ -26,9 +26,9 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; import javax.lang.model.element.ElementKind; +import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; import com.sun.source.tree.IdentifierTree; @@ -45,7 +45,6 @@ import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; import com.sun.tools.javac.jvm.*; -import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; @@ -880,6 +879,7 @@ deferredLintHandler.flush(tree.pos()); chk.checkDeprecatedAnnotation(tree.pos(), m); + // Create a new environment with local scope // for attributing the method. Env localEnv = memberEnter.methodEnv(tree, env); @@ -923,6 +923,21 @@ // Check that result type is well-formed. chk.validate(tree.restype, localEnv); + // Check that receiver type is well-formed. + if (tree.recvparam != null) { + // Use a new environment to check the receiver parameter. + // Otherwise I get "might not have been initialized" errors. + // Is there a better way? + Env 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 if ((owner.flags() & ANNOTATION) != 0) { // annotation method cannot have throws clause @@ -996,9 +1011,14 @@ } } + // Attribute all type annotations in the body + memberEnter.typeAnnotate(tree.body, localEnv, m); + annotate.flush(); + // Attribute method body. attribStat(tree.body, localEnv); } + localEnv.info.scope.leave(); result = tree.type = m.type; chk.validateAnnotations(tree.mods.annotations, m); @@ -1019,6 +1039,12 @@ memberEnter.memberEnter(tree, env); annotate.flush(); } + } else { + if (tree.init != null) { + // Field initializer expression need to be entered. + memberEnter.typeAnnotate(tree.init, env, tree.sym); + annotate.flush(); + } } VarSymbol v = tree.sym; @@ -1076,6 +1102,11 @@ new MethodSymbol(tree.flags | BLOCK, names.empty, null, env.info.scope.owner); if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; + + // Attribute all type annotations in the block + memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner); + annotate.flush(); + attribStats(tree.stats, localEnv); } else { // Create a new local environment with a local scope. @@ -1847,10 +1878,24 @@ // If enclosing class is given, attribute it, and // complete class name to be fully qualified JCExpression clazz = tree.clazz; // Class field following new - JCExpression clazzid = // Identifier in class field - (clazz.hasTag(TYPEAPPLY)) - ? ((JCTypeApply) clazz).clazz - : clazz; + JCExpression clazzid; // Identifier in class field + JCAnnotatedType annoclazzid; // Annotated type enclosing clazzid + annoclazzid = null; + + if (clazz.hasTag(TYPEAPPLY)) { + clazzid = ((JCTypeApply) clazz).clazz; + if (clazzid.hasTag(ANNOTATED_TYPE)) { + annoclazzid = (JCAnnotatedType) clazzid; + clazzid = annoclazzid.underlyingType; + } + } else { + if (clazz.hasTag(ANNOTATED_TYPE)) { + annoclazzid = (JCAnnotatedType) clazz; + clazzid = annoclazzid.underlyingType; + } else { + clazzid = clazz; + } + } JCExpression clazzid1 = clazzid; // The same in fully qualified form @@ -1865,14 +1910,30 @@ // yields a clazz T.C. Type encltype = chk.checkRefType(tree.encl.pos(), attribExpr(tree.encl, env)); + // TODO 308: in .new C, do we also want to add the type annotations + // from expr to the combined type, or not? Yes, do this. clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); - if (clazz.hasTag(TYPEAPPLY)) - clazz = make.at(tree.pos). + + if (clazz.hasTag(ANNOTATED_TYPE)) { + JCAnnotatedType annoType = (JCAnnotatedType) clazz; + List annos = annoType.annotations; + + if (annoType.underlyingType.hasTag(TYPEAPPLY)) { + clazzid1 = make.at(tree.pos). + TypeApply(clazzid1, + ((JCTypeApply) clazz).arguments); + } + + clazzid1 = make.at(tree.pos). + AnnotatedType(annos, clazzid1); + } else if (clazz.hasTag(TYPEAPPLY)) { + clazzid1 = make.at(tree.pos). TypeApply(clazzid1, ((JCTypeApply) clazz).arguments); - else - clazz = clazzid1; + } + + clazz = clazzid1; } // Attribute clazz expression and store @@ -1889,6 +1950,9 @@ tree.clazz.type = clazztype; TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1)); clazzid.type = ((JCIdent) clazzid).sym.type; + if (annoclazzid != null) { + annoclazzid.type = clazzid.type; + } if (!clazztype.isErroneous()) { if (cdef != null && clazztype.tsym.isInterface()) { log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new"); @@ -3255,8 +3319,18 @@ // Tree.Visitor. else if (ownOuter.hasTag(CLASS) && site != ownOuter) { Type normOuter = site; - if (normOuter.hasTag(CLASS)) + if (normOuter.hasTag(CLASS)) { normOuter = types.asEnclosingSuper(site, ownOuter.tsym); + if (site.getKind() == TypeKind.ANNOTATED) { + // Propagate any type annotations. + // TODO: should asEnclosingSuper do this? + // Note that the type annotations in site will be updated + // by annotateType. Therefore, modify site instead + // of creating a new AnnotatedType. + ((AnnotatedType)site).underlyingType = normOuter; + normOuter = site; + } + } if (normOuter == null) // perhaps from an import normOuter = types.erasure(ownOuter); if (normOuter != ownOuter) @@ -3644,8 +3718,15 @@ tree.type = result = checkIntersection(tree, tree.bounds); } - public void visitTypeParameter(JCTypeParameter tree) { - TypeVar typeVar = (TypeVar)tree.type; + public void visitTypeParameter(JCTypeParameter tree) { + TypeVar typeVar = (TypeVar) tree.type; + + if (tree.annotations != null && tree.annotations.nonEmpty()) { + AnnotatedType antype = new AnnotatedType(typeVar); + annotateType(antype, tree.annotations); + tree.type = antype; + } + if (!typeVar.bound.isErroneous()) { //fixup type-parameter bound computed in 'attribTypeVariables' typeVar.bound = checkIntersection(tree, tree.bounds); @@ -3741,6 +3822,44 @@ result = tree.type = syms.errType; } + public void visitAnnotatedType(JCAnnotatedType tree) { + Type underlyingType = attribType(tree.getUnderlyingType(), env); + this.attribAnnotationTypes(tree.annotations, env); + AnnotatedType antype = new AnnotatedType(underlyingType); + annotateType(antype, tree.annotations); + result = tree.type = antype; + } + + /** + * Apply the annotations to the particular type. + */ + public void annotateType(final AnnotatedType type, final List annotations) { + if (annotations.isEmpty()) + return; + annotate.typeAnnotation(new Annotate.Annotator() { + @Override + public String toString() { + return "annotate " + annotations + " onto " + type; + } + @Override + public void enterAnnotation() { + List compounds = fromAnnotations(annotations); + type.typeAnnotations = compounds; + } + }); + } + + private static List fromAnnotations(List annotations) { + if (annotations.isEmpty()) + return List.nil(); + + ListBuffer buf = ListBuffer.lb(); + for (JCAnnotation anno : annotations) { + buf.append((Attribute.TypeCompound) anno.attribute); + } + return buf.toList(); + } + public void visitErroneous(JCErroneous tree) { if (tree.errs != null) for (JCTree err : tree.errs) @@ -3972,6 +4091,12 @@ (c.flags() & ABSTRACT) == 0) { checkSerialVersionUID(tree, c); } + + // Correctly organize the postions of the type annotations + TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree); + + // Check type annotations applicability rules + validateTypeAnnotations(tree); } // where /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ @@ -4029,6 +4154,94 @@ return types.capture(type); } + private void validateTypeAnnotations(JCTree tree) { + tree.accept(typeAnnotationsValidator); + } + //where + private final JCTree.Visitor typeAnnotationsValidator = + new TreeScanner() { + 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. + chk.validateTypeAnnotation(tree, false); + } + super.visitAnnotation(tree); + } + public void visitTypeParameter(JCTypeParameter tree) { + chk.validateTypeAnnotations(tree.annotations, true); + scan(tree.bounds); + // Don't call super. + // This is needed because above we call validateTypeAnnotation with + // false, which would forbid annotations on type parameters. + // 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.restype != null && tree.restype.type != null) { + validateAnnotatedType(tree.restype, tree.restype.type); + } + super.visitMethodDef(tree); + } + public void visitVarDef(final JCVariableDecl tree) { + if (tree.sym != null && tree.sym.type != null) + validateAnnotatedType(tree, tree.sym.type); + super.visitVarDef(tree); + } + public void visitTypeCast(JCTypeCast tree) { + if (tree.clazz != null && tree.clazz.type != null) + validateAnnotatedType(tree.clazz, tree.clazz.type); + super.visitTypeCast(tree); + } + public void visitTypeTest(JCInstanceOf tree) { + if (tree.clazz != null && tree.clazz.type != null) + 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) { + + /* I would want to model this after + * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) + * and override visitSelect and visitTypeApply. + * However, we only set the annotated type in the top-level type + * of the symbol. + * Therefore, we need to override each individual location where a type + * can occur. + */ + private void validateAnnotatedType(final JCTree errtree, final Type type) { + if (type.getEnclosingType() != null && + type != type.getEnclosingType()) { + validateEnclosingAnnotatedType(errtree, type.getEnclosingType()); + } + for (Type targ : type.getTypeArguments()) { + validateAnnotatedType(errtree, targ); + } + } + private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) { + validateAnnotatedType(errtree, type); + if (type.tsym != null && + type.tsym.isStatic() && + type.getAnnotations().nonEmpty()) { + // Enclosing static classes cannot have type annotations. + log.error(errtree.pos(), "cant.annotate.static.class"); + } + } + }; + // /** diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 13:27:24 2013 -0800 @@ -26,7 +26,7 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; + import javax.tools.JavaFileManager; import com.sun.tools.javac.code.*; @@ -101,6 +101,9 @@ context.put(checkKey, this); names = Names.instance(context); + dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, + names.FIELD, names.METHOD, names.CONSTRUCTOR, + names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; log = Log.instance(context); rs = Resolve.instance(context); syms = Symtab.instance(context); @@ -572,34 +575,27 @@ if (!tree.type.isErroneous() && (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) && types.isSameType(tree.expr.type, tree.clazz.type) + && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) && !is292targetTypeCast(tree)) { log.warning(Lint.LintCategory.CAST, tree.pos(), "redundant.cast", tree.expr.type); } } //where - private boolean is292targetTypeCast(JCTypeCast tree) { - boolean is292targetTypeCast = false; - JCExpression expr = TreeInfo.skipParens(tree.expr); - if (expr.hasTag(APPLY)) { - JCMethodInvocation apply = (JCMethodInvocation)expr; - Symbol sym = TreeInfo.symbol(apply.meth); - is292targetTypeCast = sym != null && - sym.kind == MTH && - (sym.flags() & HYPOTHETICAL) != 0; - } - return is292targetTypeCast; + private boolean is292targetTypeCast(JCTypeCast tree) { + boolean is292targetTypeCast = false; + JCExpression expr = TreeInfo.skipParens(tree.expr); + if (expr.hasTag(APPLY)) { + JCMethodInvocation apply = (JCMethodInvocation)expr; + Symbol sym = TreeInfo.symbol(apply.meth); + is292targetTypeCast = sym != null && + sym.kind == MTH && + (sym.flags() & HYPOTHETICAL) != 0; } - - + return is292targetTypeCast; + } -//where - /** Is type a type variable, or a (possibly multi-dimensional) array of - * type variables? - */ - boolean isTypeVar(Type t) { - return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); - } + private static final boolean ignoreAnnotatedCasts = true; /** Check that a type is within some bounds. * @@ -853,7 +849,7 @@ // System.out.println("actuals: " + argtypes); List formals = owntype.getParameterTypes(); Type last = useVarargs ? formals.last() : null; - if (sym.name==names.init && + if (sym.name == names.init && sym.owner == syms.enumSym) formals = formals.tail.tail; List args = argtrees; @@ -1326,6 +1322,11 @@ } } + @Override + public void visitAnnotatedType(JCAnnotatedType tree) { + tree.underlyingType.accept(this); + } + /** Default visitor method: do nothing. */ @Override @@ -2246,7 +2247,7 @@ void checkImplementations(JCClassDecl tree) { checkImplementations(tree, tree.sym, tree.sym); } -//where + //where /** Check that all methods which implement some * method in `ic' conform to the method they implement. */ @@ -2587,6 +2588,13 @@ validateAnnotation(a, s); } + /** Check the type annotations. + */ + public void validateTypeAnnotations(List annotations, boolean isTypeParameter) { + for (JCAnnotation a : annotations) + validateTypeAnnotation(a, isTypeParameter); + } + /** Check an annotation of a symbol. */ private void validateAnnotation(JCAnnotation a, Symbol s) { @@ -2613,6 +2621,14 @@ } } + public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); + validateAnnotationTree(a); + + if (!isTypeAnnotation(a, isTypeParameter)) + log.error(a.pos(), "annotation.type.not.applicable"); + } + /** * Validate the proposed container 'repeatable' on the * annotation type symbol 's'. Report errors at position @@ -2795,45 +2811,90 @@ return false; } + /** Is the annotation applicable to type annotations? */ + protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Attribute.Compound atTarget = + a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) { + // An annotation without @Target is not a type annotation. + return false; + } + + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) { + return false; // error recovery + } + + Attribute.Array arr = (Attribute.Array) atValue; + for (Attribute app : arr.values) { + if (!(app instanceof Attribute.Enum)) { + return false; // recovery + } + Attribute.Enum e = (Attribute.Enum) app; + + if (e.value.name == names.TYPE_USE) + return true; + else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) + return true; + } + return false; + } + /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); + Name[] targets; + if (arr == null) { - return true; + targets = defaultTargetMetaInfo(a, s); + } else { + // TODO: can we optimize this? + targets = new Name[arr.values.length]; + for (int i=0; i typarams, List params, JCTree res, + JCVariableDecl recvparam, List thrown, Env env) { @@ -368,6 +375,15 @@ // Attribute result type, if one is given. Type restype = res == null ? syms.voidType : attr.attribType(res, env); + // Attribute receiver type, if one is given. + Type recvtype; + if (recvparam!=null) { + memberEnter(recvparam, env); + recvtype = recvparam.vartype.type; + } else { + recvtype = null; + } + // Attribute thrown exceptions. ListBuffer thrownbuf = new ListBuffer(); for (List l = thrown; l.nonEmpty(); l = l.tail) { @@ -376,10 +392,12 @@ exc = chk.checkClassType(l.head.pos(), exc); thrownbuf.append(exc); } - Type mtype = new MethodType(argbuf.toList(), + MethodType mtype = new MethodType(argbuf.toList(), restype, thrownbuf.toList(), syms.methodClass); + mtype.recvtype = recvtype; + return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype); } @@ -573,7 +591,8 @@ try { // Compute the method type m.type = signature(tree.typarams, tree.params, - tree.restype, tree.thrown, + tree.restype, tree.recvparam, + tree.thrown, localEnv); } finally { chk.setDeferredLintHandler(prevLintHandler); @@ -597,6 +616,10 @@ enclScope.enter(m); } annotateLater(tree.mods.annotations, localEnv, m); + // Visit the signature of the method. Note that + // TypeAnnotate doesn't descend into the body. + typeAnnotate(tree, localEnv, m); + if (tree.defaultValue != null) annotateDefaultValueLater(tree.defaultValue, localEnv, m); } @@ -642,7 +665,7 @@ //(a plain array type) with the more precise VarargsType --- we need //to do it this way because varargs is represented in the tree as a modifier //on the parameter declaration, and not as a distinct type of array node. - ArrayType atype = (ArrayType)tree.vartype.type; + ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType(); tree.vartype.type = atype.makeVarargs(); } Scope enclScope = enter.enterScope(env); @@ -665,6 +688,8 @@ enclScope.enter(v); } annotateLater(tree.mods.annotations, localEnv, v); + typeAnnotate(tree.vartype, env, tree.sym); + annotate.flush(); v.pos = tree.pos; } @@ -759,7 +784,7 @@ log.error(annotations.head.pos, "already.annotated", kindName(s), s); - enterAnnotations(annotations, localEnv, s); + actualEnterAnnotations(annotations, localEnv, s); } finally { log.useSource(prev); } @@ -781,7 +806,7 @@ } /** Enter a set of annotations. */ - private void enterAnnotations(List annotations, + private void actualEnterAnnotations(List annotations, Env env, Symbol s) { Map> annotated = @@ -817,11 +842,11 @@ && s.owner.kind != MTH && types.isSameType(c.type, syms.deprecatedType)) { s.flags_field |= Flags.DEPRECATED; - } + } } - s.annotations.setAttributesWithCompletion( - annotate.new AnnotateRepeatedContext(env, annotated, pos, log)); + s.annotations.setDeclarationAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log, false)); } /** Queue processing of an attribute default value. */ @@ -900,6 +925,12 @@ // create an environment for evaluating the base clauses Env baseEnv = baseEnv(tree, env); + if (tree.extending != null) + typeAnnotate(tree.extending, baseEnv, sym); + for (JCExpression impl : tree.implementing) + typeAnnotate(impl, baseEnv, sym); + annotate.flush(); + // Determine supertype. Type supertype = (tree.extending != null) @@ -969,10 +1000,15 @@ if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; annotateLater(tree.mods.annotations, baseEnv, c); + // class type parameters use baseEnv but everything uses env chk.checkNonCyclicDecl(tree); attr.attribTypeVariables(tree.typarams, baseEnv); + // Do this here, where we have the symbol. + for (JCTypeParameter tp : tree.typarams) + typeAnnotate(tp, baseEnv, sym); + annotate.flush(); // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && @@ -1050,12 +1086,120 @@ } finally { isFirst = true; } + } + annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree)); + } - // commit pending annotations - annotate.flush(); + private void actualEnterTypeAnnotations(final List annotations, + final Env env, + final Symbol s) { + Map> annotated = + new LinkedHashMap>(); + Map pos = + new HashMap(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { + JCAnnotation a = al.head; + Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a, + syms.annotationType, + env); + if (tc == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (source.allowRepeatedAnnotations()) { + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(tc); + annotated.put(a.type.tsym, l); + pos.put(tc, a.pos()); + } else { + log.error(a.pos(), "duplicate.annotation"); + } + } else { + annotated.put(a.type.tsym, ListBuffer.of(tc)); + pos.put(tc, a.pos()); + } + } + + s.annotations.appendTypeAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true)); + } + + public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) { + tree.accept(new TypeAnnotate(env, sym)); + } + + /** + * We need to use a TreeScanner, because it is not enough to visit the top-level + * annotations. We also need to visit type arguments, etc. + */ + private class TypeAnnotate extends TreeScanner { + private Env env; + private Symbol sym; + + public TypeAnnotate(final Env env, final Symbol sym) { + this.env = env; + this.sym = sym; + } + + void annotateTypeLater(final List annotations) { + if (annotations.isEmpty()) { + return; + } + + annotate.normal(new Annotate.Annotator() { + @Override + public String toString() { + return "type annotate " + annotations + " onto " + sym + " in " + sym.owner; + } + @Override + public void enterAnnotation() { + JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + try { + actualEnterTypeAnnotations(annotations, env, sym); + } finally { + log.useSource(prev); + } + } + }); + } + + @Override + public void visitAnnotatedType(final JCAnnotatedType tree) { + annotateTypeLater(tree.annotations); + super.visitAnnotatedType(tree); + } + + @Override + public void visitTypeParameter(final JCTypeParameter tree) { + annotateTypeLater(tree.annotations); + super.visitTypeParameter(tree); + } + + @Override + public void visitNewArray(final JCNewArray tree) { + annotateTypeLater(tree.annotations); + for (List dimAnnos : tree.dimAnnotations) + annotateTypeLater(dimAnnos); + super.visitNewArray(tree); + } + + @Override + public void visitMethodDef(final JCMethodDecl tree) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + scan(tree.defaultValue); + // Do not annotate the body, just the signature. + // scan(tree.body); } } + private Env baseEnv(JCClassDecl tree, Env env) { Scope baseScope = new Scope(tree.sym); //import already entered local classes into base scope diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -55,7 +55,6 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Set; import javax.lang.model.element.ElementVisitor; @@ -696,7 +695,7 @@ if (varargsFormal == null && argtypes.size() != formals.size()) { - report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } while (argtypes.nonEmpty() && formals.head != varargsFormal) { @@ -707,7 +706,7 @@ } if (formals.head != varargsFormal) { - report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } if (useVarargs) { @@ -724,7 +723,7 @@ } } - private void report(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { + private void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { boolean inferDiag = inferenceContext != infer.emptyContext; InapplicableMethodException ex = inferDiag ? infer.inferenceException : inapplicableMethodException; @@ -748,7 +747,7 @@ } else { if (!isAccessible(env, t)) { Symbol location = env.enclClass.sym; - report(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); + reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); } } } @@ -761,7 +760,7 @@ @Override public void report(DiagnosticPosition pos, JCDiagnostic details) { - report(methodDiag, deferredAttrContext.inferenceContext, details); + reportMC(methodDiag, deferredAttrContext.inferenceContext, details); } }; return new MethodResultInfo(to, checkContext); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -483,6 +483,7 @@ tree.restype = translate(tree.restype, null); tree.typarams = List.nil(); tree.params = translateVarDefs(tree.params); + tree.recvparam = translate(tree.recvparam, null); tree.thrown = translate(tree.thrown, null); tree.body = translate(tree.body, tree.sym.erasure(types).getReturnType()); tree.type = erasure(tree.type); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -351,8 +351,8 @@ /** Read a byte. */ - byte nextByte() { - return buf[bp++]; + int nextByte() { + return buf[bp++] & 0xFF; } /** Read an integer. @@ -1172,6 +1172,19 @@ } }, + new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { + protected void read(Symbol sym, int attrLen) { + attachTypeAnnotations(sym); + } + }, + + new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { + protected void read(Symbol sym, int attrLen) { + attachTypeAnnotations(sym); + } + }, + + // The following attributes for a Code attribute are not currently handled // StackMapTable // SourceDebugExtension @@ -1381,6 +1394,17 @@ } } + void attachTypeAnnotations(final Symbol sym) { + int numAttributes = nextChar(); + if (numAttributes != 0) { + ListBuffer proxies = + ListBuffer.lb(); + for (int i = 0; i < numAttributes; i++) + proxies.append(readTypeAnnotation()); + annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList())); + } + } + /** Attach the default value for an annotation element. */ void attachAnnotationDefault(final Symbol sym) { @@ -1427,6 +1451,111 @@ return new CompoundAnnotationProxy(t, pairs.toList()); } + TypeAnnotationProxy readTypeAnnotation() { + TypeAnnotationPosition position = readPosition(); + CompoundAnnotationProxy proxy = readCompoundAnnotation(); + + return new TypeAnnotationProxy(proxy, position); + } + + TypeAnnotationPosition readPosition() { + int tag = nextByte(); // TargetType tag is a byte + + if (!TargetType.isValidTargetTypeValue(tag)) + throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); + + TypeAnnotationPosition position = new TypeAnnotationPosition(); + TargetType type = TargetType.fromTargetTypeValue(tag); + + position.type = type; + + switch (type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + position.offset = nextChar(); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + int table_length = nextChar(); + position.lvarOffset = new int[table_length]; + position.lvarLength = new int[table_length]; + position.lvarIndex = new int[table_length]; + + for (int i = 0; i < table_length; ++i) { + position.lvarOffset[i] = nextChar(); + position.lvarLength[i] = nextChar(); + position.lvarIndex[i] = nextChar(); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + position.exception_index = nextByte(); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + position.parameter_index = nextByte(); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + position.parameter_index = nextByte(); + position.bound_index = nextByte(); + break; + // class extends or implements clause + case CLASS_EXTENDS: + position.type_index = nextChar(); + break; + // throws + case THROWS: + position.type_index = nextChar(); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + position.parameter_index = nextByte(); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + position.offset = nextChar(); + position.type_index = nextByte(); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + position.parameter_index = nextByte(); + break; + case UNKNOWN: + throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + position); + } + + { // See whether there is location info and read it + int len = nextByte(); + ListBuffer loc = ListBuffer.lb(); + for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i) + loc = loc.append(nextByte()); + position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList()); + } + + return position; + } + Attribute readAttributeValue() { char c = (char) buf[bp++]; switch (c) { @@ -1748,7 +1877,7 @@ Annotations annotations = sym.annotations; List newList = deproxyCompoundList(l); if (annotations.pendingCompletion()) { - annotations.setAttributes(newList); + annotations.setDeclarationAttributes(newList); } else { annotations.append(newList); } @@ -1758,6 +1887,39 @@ } } + class TypeAnnotationCompleter extends AnnotationCompleter { + + List proxies; + + TypeAnnotationCompleter(Symbol sym, + List proxies) { + super(sym, List.nil()); + this.proxies = proxies; + } + + List deproxyTypeCompoundList(List proxies) { + ListBuffer buf = ListBuffer.lb(); + for (TypeAnnotationProxy proxy: proxies) { + Attribute.Compound compound = deproxyCompound(proxy.compound); + Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position); + buf.add(typeCompound); + } + return buf.toList(); + } + + @Override + public void enterAnnotation() { + JavaFileObject previousClassFile = currentClassFile; + try { + currentClassFile = classFile; + List newList = deproxyTypeCompoundList(proxies); + sym.annotations.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes())); + } finally { + currentClassFile = previousClassFile; + } + } + } + /************************************************************************ * Reading Symbols diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -31,12 +31,14 @@ import java.util.Set; import java.util.HashSet; +import javax.lang.model.type.TypeKind; import javax.tools.JavaFileManager; import javax.tools.FileObject; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.RetentionPolicy; +import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Types.UniqueType; @@ -47,7 +49,6 @@ import com.sun.tools.javac.jvm.Pool.Variable; import com.sun.tools.javac.util.*; -import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.*; @@ -68,19 +69,17 @@ protected static final Context.Key classWriterKey = new Context.Key(); - private final Symtab syms; - private final Options options; /** Switch: verbose output. */ private boolean verbose; - /** Switch: scramble private names. + /** Switch: scramble private field names. */ private boolean scramble; - /** Switch: scramble private names. + /** Switch: scramble all field names. */ private boolean scrambleAll; @@ -96,7 +95,7 @@ */ private boolean genCrt; - /** Switch: describe the generated stackmap + /** Switch: describe the generated stackmap. */ boolean debugstackmap; @@ -114,7 +113,7 @@ private Types types; /** The initial sizes of the data and constant pool buffers. - * sizes are increased when buffers get full. + * Sizes are increased when buffers get full. */ static final int DATA_BUF_SIZE = 0x0fff0; static final int POOL_BUF_SIZE = 0x1fff0; @@ -181,7 +180,6 @@ log = Log.instance(context); names = Names.instance(context); - syms = Symtab.instance(context); options = Options.instance(context); target = Target.instance(context); source = Source.instance(context); @@ -279,6 +277,7 @@ /** Assemble signature of given type in string buffer. */ void assembleSig(Type type) { + type = type.unannotatedType(); switch (type.getTag()) { case BYTE: sigbuf.appendByte('B'); @@ -379,6 +378,7 @@ } void assembleClassSig(Type type) { + type = type.unannotatedType(); ClassType ct = (ClassType)type; ClassSymbol c = (ClassSymbol)ct.tsym; enterInner(c); @@ -722,6 +722,7 @@ acount++; } acount += writeJavaAnnotations(sym.getRawAttributes()); + acount += writeTypeAnnotations(sym.getRawTypeAttributes()); return acount; } @@ -838,6 +839,76 @@ return attrCount; } + int writeTypeAnnotations(List typeAnnos) { + if (typeAnnos.isEmpty()) return 0; + + ListBuffer visibles = ListBuffer.lb(); + ListBuffer 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 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) { + // 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); + continue; + } + } + if (!tc.position.emitToClassfile()) + continue; + switch (types.getRetention(tc)) { + case SOURCE: break; + case CLASS: invisibles.append(tc); break; + case RUNTIME: visibles.append(tc); break; + default: ;// /* fail soft */ throw new AssertionError(vis); + } + } + + int attrCount = 0; + if (visibles.length() != 0) { + int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations); + databuf.appendChar(visibles.length()); + for (Attribute.TypeCompound p : visibles) + writeTypeAnnotation(p); + endAttr(attrIndex); + attrCount++; + } + + if (invisibles.length() != 0) { + int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations); + databuf.appendChar(invisibles.length()); + for (Attribute.TypeCompound p : invisibles) + writeTypeAnnotation(p); + endAttr(attrIndex); + attrCount++; + } + + return attrCount; + } + /** A visitor to write an attribute including its leading * single-character marker. */ @@ -914,6 +985,94 @@ p.snd.accept(awriter); } } + + void writeTypeAnnotation(Attribute.TypeCompound c) { + writePosition(c.position); + writeCompoundAttribute(c); + } + + void writePosition(TypeAnnotationPosition p) { + databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte + switch (p.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + databuf.appendChar(p.offset); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + databuf.appendChar(p.lvarOffset.length); // for table length + for (int i = 0; i < p.lvarOffset.length; ++i) { + databuf.appendChar(p.lvarOffset[i]); + databuf.appendChar(p.lvarLength[i]); + databuf.appendChar(p.lvarIndex[i]); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + databuf.appendByte(p.exception_index); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + databuf.appendByte(p.parameter_index); + databuf.appendByte(p.bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + databuf.appendChar(p.type_index); + break; + // throws + case THROWS: + databuf.appendChar(p.type_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + databuf.appendChar(p.offset); + databuf.appendByte(p.type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + case UNKNOWN: + throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p); + } + + { // Append location data for generics/arrays. + databuf.appendByte(p.location.size()); + java.util.List loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location); + for (int i : loc) + databuf.appendByte((byte)i); + } + } + /********************************************************************** * Writing Objects **********************************************************************/ @@ -1661,6 +1820,7 @@ acount += writeFlagAttrs(c.flags()); acount += writeJavaAnnotations(c.getRawAttributes()); + acount += writeTypeAnnotations(c.getRawTypeAttributes()); acount += writeEnclosingMethodAttribute(c); acount += writeExtraClassAttributes(c); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -1924,17 +1924,70 @@ if (length < Character.MAX_VALUE) { v.length = length; putVar(v); + fillLocalVarPosition(v); } } } state.defined.excl(adr); } + private void fillLocalVarPosition(LocalVar lv) { + if (lv == null || lv.sym == null + || lv.sym.annotations.isTypesEmpty()) + return; + for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { + TypeAnnotationPosition p = ta.position; + p.lvarOffset = new int[] { (int)lv.start_pc }; + p.lvarLength = new int[] { (int)lv.length }; + p.lvarIndex = new int[] { (int)lv.reg }; + p.isValidOffset = true; + } + } + + // Method to be called after compressCatchTable to + // fill in the exception table index for type + // annotations on exception parameters. + public void fillExceptionParameterPositions() { + for (int i = 0; i < varBufferSize; ++i) { + LocalVar lv = varBuffer[i]; + if (lv == null || lv.sym == null + || lv.sym.annotations.isTypesEmpty() + || !lv.sym.isExceptionParameter()) + return; + + int exidx = findExceptionIndex(lv); + + for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { + TypeAnnotationPosition p = ta.position; + p.exception_index = exidx; + } + } + } + + private int findExceptionIndex(LocalVar lv) { + List 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) { + return i; + } + } + return -1; + } + /** Put a live variable range into the buffer to be output to the * class file. */ void putVar(LocalVar var) { - if (!varDebugInfo) return; + // Keep local variables if + // 1) we need them for debug information + // 2) it is an exception type and it contains type annotations + if (!varDebugInfo && + (!var.sym.isExceptionParameter() || + var.sym.annotations.isTypesEmpty())) return; if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return; if (varBuffer == null) varBuffer = new LocalVar[20]; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -1016,8 +1016,11 @@ code.frameBeforeLast = null; } - //compress exception table + // Compress exception table code.compressCatchTable(); + + // Fill in type annotation positions for exception parameters + code.fillExceptionParameterPositions(); } } @@ -1738,6 +1741,7 @@ *************************************************************************/ public void visitApply(JCMethodInvocation tree) { + setTypeAnnotationPositions(tree.pos); // Generate code for method. Item m = genExpr(tree.meth, methodType); // Generate code for all arguments, where the expected types are @@ -1775,10 +1779,48 @@ result = items.makeStackItem(pt); } + private void setTypeAnnotationPositions(int treePos) { + MethodSymbol meth = code.meth; + + 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; + } + } + + if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR + && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT) + 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; + } + } + + 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; + } + } + } + } + public void visitNewClass(JCNewClass tree) { // Enclosing instances or anonymous classes should have been eliminated // by now. Assert.check(tree.encl == null && tree.def == null); + setTypeAnnotationPositions(tree.pos); code.emitop2(new_, makeRef(tree.pos(), tree.type)); code.emitop0(dup); @@ -1793,6 +1835,7 @@ } public void visitNewArray(JCNewArray tree) { + setTypeAnnotationPositions(tree.pos); if (tree.elems != null) { Type elemtype = types.elemtype(tree.type); @@ -2122,6 +2165,7 @@ } public void visitTypeCast(JCTypeCast tree) { + setTypeAnnotationPositions(tree.pos); result = genExpr(tree.expr, tree.clazz.type).load(); // Additional code is only needed if we cast to a reference type // which is not statically a supertype of the expression's type. @@ -2138,6 +2182,7 @@ } public void visitTypeTest(JCInstanceOf tree) { + setTypeAnnotationPositions(tree.pos); genExpr(tree.expr, tree.expr.type).load(); code.emitop2(instanceof_, makeRef(tree.pos(), tree.clazz.type)); result = items.makeStackItem(syms.booleanType); @@ -2184,7 +2229,7 @@ code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type)); result = items.makeStackItem(pt); return; - } + } Symbol ssym = TreeInfo.symbol(tree.selected); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -158,7 +158,7 @@ return false; /* temporary code for backwards compatibility */ - for (Attribute.Compound a: c.annotations.getAttributes()) { + for (Attribute.Compound a: c.annotations.getDeclarationAttributes()) { if (a.type.tsym == syms.nativeHeaderType_old.tsym) return true; } @@ -167,7 +167,7 @@ for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) { if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0) return true; - for (Attribute.Compound a: i.sym.annotations.getAttributes()) { + for (Attribute.Compound a: i.sym.annotations.getDeclarationAttributes()) { if (a.type.tsym == syms.nativeHeaderType.tsym) return true; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -513,7 +513,7 @@ */ public CompileState shouldStopPolicyIfNoError; - /** A queue of all as yet unattributed classes.oLo + /** A queue of all as yet unattributed classes. */ public Todo todo; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,9 +25,9 @@ package com.sun.tools.javac.model; +import java.lang.annotation.Annotation; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -333,4 +333,28 @@ return results; } + + public List typeAnnotationsOf(TypeMirror type) { + // TODO: these methods can be removed. + return null; // ((Type)type).typeAnnotations; + } + + public A typeAnnotationOf(TypeMirror type, + Class annotationType) { + // TODO: these methods can be removed. + return null; // JavacElements.getAnnotation(((Type)type).typeAnnotations, annotationType); + } + + public TypeMirror receiverTypeOf(ExecutableType type) { + return ((Type)type).asMethodType().recvtype; + } + + /* + public A receiverTypeAnnotationOf( + ExecutableType type, Class annotationType) { + return JavacElements.getAnnotation( + ((Type)type).asMethodType().receiverTypeAnnotations, + annotationType); + }*/ + } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -88,6 +88,41 @@ /** End position mappings container */ private final AbstractEndPosTable endPosTable; + // Because of javac's limited lookahead, some contexts are ambiguous in + // the presence of type annotations even though they are not ambiguous + // in the absence of type annotations. Consider this code: + // void m(String [] m) { } + // void m(String ... m) { } + // After parsing "String", javac calls bracketsOpt which immediately + // returns if the next character is not '['. Similarly, javac can see + // if the next token is ... and in that case parse an ellipsis. But in + // the presence of type annotations: + // void m(String @A [] m) { } + // void m(String @A ... m) { } + // no finite lookahead is enough to determine whether to read array + // levels or an ellipsis. Furthermore, if you call bracketsOpt, then + // bracketsOpt first reads all the leading annotations and only then + // discovers that it needs to fail. bracketsOpt needs a way to push + // back the extra annotations that it read. (But, bracketsOpt should + // not *always* be allowed to push back extra annotations that it finds + // -- in most contexts, any such extra annotation is an error. + // + // The following two variables permit type annotations that have + // already been read to be stored for later use. Alternate + // implementations are possible but would cause much larger changes to + // the parser. + + /** Type annotations that have already been read but have not yet been used. **/ + private List typeAnnotationsPushedBack = List.nil(); + + /** + * If the parser notices extra annotations, then it either immediately + * issues an error (if this variable is false) or places the extra + * annotations in variable typeAnnotationsPushedBack (if this variable + * is true). + */ + private boolean permitTypeAnnotationsPushBack = false; + interface ErrorRecoveryAction { JCTree doRecover(JavacParser parser); } @@ -126,6 +161,7 @@ this.allowDefaultMethods = source.allowDefaultMethods(); this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast(); + this.allowTypeAnnotations = source.allowTypeAnnotations(); this.keepDocComments = keepDocComments; docComments = newDocCommentTable(keepDocComments, fac); this.keepLineMap = keepLineMap; @@ -215,6 +251,20 @@ */ boolean keepLineMap; + /** Switch: should we recognize type annotations? + */ + boolean allowTypeAnnotations; + + /** Switch: is "this" allowed as an identifier? + * This is needed to parse receiver types. + */ + boolean allowThisIdent; + + /** The type of the method receiver, as specified by a first "this" parameter. + */ + JCVariableDecl receiverParam; + + /** When terms are parsed, the mode determines which is expected: * mode = EXPR : an expression * mode = TYPE : a type @@ -558,6 +608,18 @@ nextToken(); return name; } + } else if (token.kind == THIS) { + if (allowThisIdent) { + // Make sure we're using a supported source version. + checkTypeAnnotations(); + Name name = token.name(); + nextToken(); + return name; + } else { + error(token.pos, "this.as.identifier"); + nextToken(); + return names.error; + } } else if (token.kind == UNDERSCORE) { warning(token.pos, "underscore.as.identifier"); Name name = token.name(); @@ -570,14 +632,21 @@ } /** - * Qualident = Ident { DOT Ident } + * Qualident = Ident { DOT [Annotations] Ident } */ - public JCExpression qualident() { + public JCExpression qualident(boolean allowAnnos) { JCExpression t = toP(F.at(token.pos).Ident(ident())); while (token.kind == DOT) { int pos = token.pos; nextToken(); + List tyannos = null; + if (allowAnnos) { + tyannos = typeAnnotationsOpt(); + } t = toP(F.at(pos).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } } return t; } @@ -686,7 +755,7 @@ nextToken(); return t; } -//where + //where boolean isZero(String s) { char[] cs = s.toCharArray(); int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10); @@ -706,7 +775,34 @@ return term(EXPR); } + /** + * parses (optional) type annotations followed by a type. If the + * annotations are present before the type and are not consumed during array + * parsing, this method returns a {@link JCAnnotatedType} consisting of + * these annotations and the underlying type. Otherwise, it returns the + * underlying type. + * + *

+ * + * Note that this method sets {@code mode} to {@code TYPE} first, before + * parsing annotations. + */ public JCExpression parseType() { + List annotations = typeAnnotationsOpt(); + return parseType(annotations); + } + + public JCExpression parseType(List annotations) { + JCExpression result = unannotatedType(); + + if (annotations.nonEmpty()) { + result = insertAnnotationsToMostInner(result, annotations, false); + } + + return result; + } + + public JCExpression unannotatedType() { return term(TYPE); } @@ -864,7 +960,7 @@ opStackSupply.add(opStack); return t; } -//where + //where /** Construct a binary or type test node. */ private JCExpression makeOp(int pos, @@ -943,9 +1039,9 @@ * | NEW [TypeArguments] Creator * | "(" Arguments ")" "->" ( Expression | Block ) * | Ident "->" ( Expression | Block ) - * | Ident { "." Ident } + * | [Annotations] Ident { "." [Annotations] Ident } * | Expression3 MemberReferenceSuffix - * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) + * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) * | Arguments * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) * ] @@ -1067,6 +1163,34 @@ typeArgs = null; } else return illegal(); break; + case MONKEYS_AT: + // Only annotated cast types are valid + List typeAnnos = typeAnnotationsOpt(); + if (typeAnnos.isEmpty()) { + // else there would be no '@' + throw new AssertionError("Expected type annotations, but found none!"); + } + + JCExpression expr = term3(); + + if ((mode & TYPE) == 0) { + // Type annotations on class literals no longer legal + if (!expr.hasTag(Tag.SELECT)) { + return illegal(typeAnnos.head.pos); + } + JCFieldAccess sel = (JCFieldAccess)expr; + + if (sel.name != names._class) { + return illegal(); + } else { + log.error(token.pos, "no.annotations.on.dot.class"); + return expr; + } + } else { + // Type annotations targeting a cast + t = insertAnnotationsToMostInner(expr, typeAnnos, false); + } + break; case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM: if (typeArgs != null) return illegal(); if ((mode & EXPR) != 0 && peekToken(ARROW)) { @@ -1075,6 +1199,13 @@ t = toP(F.at(token.pos).Ident(ident())); loop: while (true) { pos = token.pos; + final List annos = typeAnnotationsOpt(); + + // need to report an error later if LBRACKET is for array + // index access rather than array creation level + if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS) + return illegal(annos.head.pos); + switch (token.kind) { case LBRACKET: nextToken(); @@ -1082,11 +1213,23 @@ nextToken(); t = bracketsOpt(t); t = toP(F.at(pos).TypeArray(t)); - t = bracketsSuffix(t); + if (annos.nonEmpty()) { + t = toP(F.at(pos).AnnotatedType(annos, t)); + } + // .class is only allowed if there were no annotations + JCExpression nt = bracketsSuffix(t); + if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) { + // t and nt are different if bracketsSuffix parsed a .class. + // The check for nonEmpty covers the case when the whole array is annotated. + // Helper method isAnnotated looks for annos deeply within t. + syntaxError("no.annotations.on.dot.class"); + } + t = nt; } else { if ((mode & EXPR) != 0) { mode = EXPR; JCExpression t1 = term(); + if (!annos.isEmpty()) t = illegal(annos.head.pos); t = to(F.at(pos).Indexed(t, t1)); } accept(RBRACKET); @@ -1096,6 +1239,7 @@ if ((mode & EXPR) != 0) { mode = EXPR; t = arguments(typeArgs, t); + if (!annos.isEmpty()) t = illegal(annos.head.pos); typeArgs = null; } break loop; @@ -1136,9 +1280,25 @@ break loop; } } + + List tyannos = null; + if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { + tyannos = typeAnnotationsOpt(); + } // typeArgs saved for next loop iteration. t = toP(F.at(pos).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } break; + case ELLIPSIS: + if (this.permitTypeAnnotationsPushBack) { + this.typeAnnotationsPushedBack = annos; + } else if (annos.nonEmpty()) { + // Don't return here -- error recovery attempt + illegal(annos.head.pos); + } + break loop; case LT: if ((mode & TYPE) == 0 && isUnboundMemberRef()) { //this is an unbound method reference whose qualifier @@ -1212,6 +1372,8 @@ if (typeArgs != null) illegal(); while (true) { int pos1 = token.pos; + final List annos = typeAnnotationsOpt(); + if (token.kind == LBRACKET) { nextToken(); if ((mode & TYPE) != 0) { @@ -1225,6 +1387,9 @@ mode = EXPR; continue; } + if (annos.nonEmpty()) { + t = toP(F.at(pos1).AnnotatedType(annos, t)); + } return t; } mode = oldmode; @@ -1253,7 +1418,15 @@ t = innerCreator(pos2, typeArgs, t); typeArgs = null; } else { + List tyannos = null; + if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { + // is the mode check needed? + tyannos = typeAnnotationsOpt(); + } t = toP(F.at(pos1).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); typeArgs = null; } @@ -1263,6 +1436,12 @@ accept(COLCOL); t = memberReferenceSuffix(pos1, t); } else { + if (!annos.isEmpty()) { + if (permitTypeAnnotationsPushBack) + typeAnnotationsPushedBack = annos; + else + return illegal(annos.head.pos); + } break; } } @@ -1321,7 +1500,7 @@ ParensResult analyzeParens() { int depth = 0; boolean type = false; - for (int lookahead = 0 ; ; lookahead++) { + outer: for (int lookahead = 0 ; ; lookahead++) { TokenKind tk = S.token(lookahead).kind; switch (tk) { case EXTENDS: case SUPER: case COMMA: @@ -1382,9 +1561,36 @@ break; case FINAL: case ELLIPSIS: - case MONKEYS_AT: //those can only appear in explicit lambdas return ParensResult.EXPLICIT_LAMBDA; + case MONKEYS_AT: + type = true; + lookahead += 1; //skip '@' + while (peekToken(lookahead, DOT)) { + lookahead += 2; + } + if (peekToken(lookahead, LPAREN)) { + lookahead++; + //skip annotation values + int nesting = 0; + for (; ; lookahead++) { + TokenKind tk2 = S.token(lookahead).kind; + switch (tk2) { + case EOF: + return ParensResult.PARENS; + case LPAREN: + nesting++; + break; + case RPAREN: + nesting--; + if (nesting == 0) { + continue outer; + } + break; + } + } + } + break; case LBRACKET: if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda @@ -1618,25 +1824,27 @@ /** * {@literal * TypeArgument = Type - * | "?" - * | "?" EXTENDS Type {"&" Type} - * | "?" SUPER Type + * | [Annotations] "?" + * | [Annotations] "?" EXTENDS Type {"&" Type} + * | [Annotations] "?" SUPER Type * } */ JCExpression typeArgument() { - if (token.kind != QUES) return parseType(); + List annotations = typeAnnotationsOpt(); + if (token.kind != QUES) return parseType(annotations); int pos = token.pos; nextToken(); + JCExpression result; if (token.kind == EXTENDS) { TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS)); nextToken(); JCExpression bound = parseType(); - return F.at(pos).Wildcard(t, bound); + result = F.at(pos).Wildcard(t, bound); } else if (token.kind == SUPER) { TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); nextToken(); JCExpression bound = parseType(); - return F.at(pos).Wildcard(t, bound); + result = F.at(pos).Wildcard(t, bound); } else if (LAX_IDENTIFIER.accepts(token.kind)) { //error recovery TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); @@ -1644,11 +1852,15 @@ JCIdent id = toP(F.at(token.pos).Ident(ident())); JCErroneous err = F.at(pos).Erroneous(List.of(wc, id)); reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER); - return err; + result = err; } else { TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND)); - return toP(F.at(pos).Wildcard(t, null)); + result = toP(F.at(pos).Wildcard(t, null)); } + if (!annotations.isEmpty()) { + result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result)); + } + return result; } JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) { @@ -1657,22 +1869,51 @@ return toP(F.at(pos).TypeApply(t, args)); } - /** BracketsOpt = {"[" "]"} + /** + * BracketsOpt = { [Annotations] "[" "]" }* + * + *

+ * + * annotations is the list of annotations targeting + * the expression t. */ - private JCExpression bracketsOpt(JCExpression t) { + private JCExpression bracketsOpt(JCExpression t, + List annotations) { + List nextLevelAnnotations = typeAnnotationsOpt(); + if (token.kind == LBRACKET) { int pos = token.pos; nextToken(); - t = bracketsOptCont(t, pos); - F.at(pos); + t = bracketsOptCont(t, pos, nextLevelAnnotations); + } else if (!nextLevelAnnotations.isEmpty()) { + if (permitTypeAnnotationsPushBack) { + this.typeAnnotationsPushedBack = nextLevelAnnotations; + } else { + return illegal(nextLevelAnnotations.head.pos); + } + } + + if (!annotations.isEmpty()) { + t = toP(F.at(token.pos).AnnotatedType(annotations, t)); } return t; } - private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) { + /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ] + */ + private JCExpression bracketsOpt(JCExpression t) { + return bracketsOpt(t, List.nil()); + } + + private JCExpression bracketsOptCont(JCExpression t, int pos, + List annotations) { accept(RBRACKET); t = bracketsOpt(t); - return toP(F.at(pos).TypeArray(t)); + t = toP(F.at(pos).TypeArray(t)); + if (annotations.nonEmpty()) { + t = toP(F.at(pos).AnnotatedType(annotations, t)); + } + return t; } /** BracketsSuffixExpr = "." CLASS @@ -1686,7 +1927,7 @@ accept(CLASS); if (token.pos == endPosTable.errorEndPos) { // error recovery - Name name = null; + Name name; if (LAX_IDENTIFIER.accepts(token.kind)) { name = token.name(); nextToken(); @@ -1724,8 +1965,8 @@ if (token.kind == LT) { typeArgs = typeArguments(false); } - Name refName = null; - ReferenceMode refMode = null; + Name refName; + ReferenceMode refMode; if (token.kind == NEW) { refMode = ReferenceMode.NEW; refName = names.init; @@ -1737,18 +1978,31 @@ return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs)); } - /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) + /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) */ JCExpression creator(int newpos, List typeArgs) { + List newAnnotations = typeAnnotationsOpt(); + switch (token.kind) { case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: - if (typeArgs == null) - return arrayCreatorRest(newpos, basicType()); + if (typeArgs == null) { + if (newAnnotations.isEmpty()) { + return arrayCreatorRest(newpos, basicType()); + } else { + return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType()))); + } + } break; default: } - JCExpression t = qualident(); + 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; @@ -1766,7 +2020,13 @@ } int pos = token.pos; nextToken(); + List tyannos = typeAnnotationsOpt(); t = toP(F.at(pos).Select(t, ident())); + + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } + if (token.kind == LT) { lastTypeargsPos = token.pos; checkGenerics(); @@ -1775,7 +2035,7 @@ } } mode = oldmode; - if (token.kind == LBRACKET) { + if (token.kind == LBRACKET || token.kind == MONKEYS_AT) { JCExpression e = arrayCreatorRest(newpos, t); if (diamondFound) { reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond"); @@ -1796,7 +2056,15 @@ } return e; } else if (token.kind == LPAREN) { - return classCreatorRest(newpos, null, typeArgs, t); + JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); + if (newClass.def != null) { + assert newClass.def.mods.annotations.isEmpty(); + if (newAnnotations.nonEmpty()) { + newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos); + newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); + } + } + return newClass; } else { setErrorEndPos(token.pos); reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET); @@ -1805,10 +2073,17 @@ } } - /** InnerCreator = Ident [TypeArguments] ClassCreatorRest + /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest */ JCExpression innerCreator(int newpos, List typeArgs, JCExpression encl) { + List newAnnotations = typeAnnotationsOpt(); + JCExpression t = toP(F.at(token.pos).Ident(ident())); + + if (newAnnotations.nonEmpty()) { + t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t)); + } + if (token.kind == LT) { int oldmode = mode; checkGenerics(); @@ -1818,35 +2093,65 @@ return classCreatorRest(newpos, encl, typeArgs, t); } - /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer - * | Expression "]" {"[" Expression "]"} BracketsOpt ) + /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer + * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt ) */ JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { + List annos = typeAnnotationsOpt(); + accept(LBRACKET); if (token.kind == RBRACKET) { accept(RBRACKET); - elemtype = bracketsOpt(elemtype); + elemtype = bracketsOpt(elemtype, annos); if (token.kind == LBRACE) { - return arrayInitializer(newpos, elemtype); + JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype); + if (annos.nonEmpty()) { + // when an array initializer is present then + // the parsed annotations should target the + // new array tree + // bracketsOpt inserts the annotation in + // elemtype, and it needs to be corrected + // + JCAnnotatedType annotated = (JCAnnotatedType)elemtype; + assert annotated.annotations == annos; + na.annotations = annotated.annotations; + na.elemtype = annotated.underlyingType; + } + return na; } else { JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.nil(), null)); return syntaxError(token.pos, List.of(t), "array.dimension.missing"); } } else { ListBuffer dims = new ListBuffer(); + + // maintain array dimension type annotations + ListBuffer> dimAnnotations = ListBuffer.lb(); + dimAnnotations.append(annos); + dims.append(parseExpression()); accept(RBRACKET); - while (token.kind == LBRACKET) { + while (token.kind == LBRACKET + || token.kind == MONKEYS_AT) { + List maybeDimAnnos = typeAnnotationsOpt(); int pos = token.pos; nextToken(); if (token.kind == RBRACKET) { - elemtype = bracketsOptCont(elemtype, pos); + elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); } else { - dims.append(parseExpression()); - accept(RBRACKET); + if (token.kind == RBRACKET) { // no dimension + elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); + } else { + dimAnnotations.append(maybeDimAnnos); + dims.append(parseExpression()); + accept(RBRACKET); + } } } - return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); + + JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); + na.dimAnnotations = dimAnnotations.toList(); + return na; } } @@ -2254,6 +2559,7 @@ } /** CatchClause = CATCH "(" FormalParameter ")" Block + * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below. */ protected JCCatch catchClause() { int pos = token.pos; @@ -2276,7 +2582,9 @@ while (token.kind == BAR) { checkMulticatch(); nextToken(); - catchTypes.add(qualident()); + // Instead of qualident this is now parseType. + // But would that allow too much, e.g. arrays or generics? + catchTypes.add(parseType()); } return catchTypes.toList(); } @@ -2377,16 +2685,28 @@ } /** AnnotationsOpt = { '@' Annotation } + * + * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION */ - List annotationsOpt() { + List annotationsOpt(Tag kind) { if (token.kind != MONKEYS_AT) return List.nil(); // optimization ListBuffer buf = new ListBuffer(); + int prevmode = mode; while (token.kind == MONKEYS_AT) { int pos = token.pos; nextToken(); - buf.append(annotation(pos)); + buf.append(annotation(pos, kind)); } - return buf.toList(); + lastmode = mode; + mode = prevmode; + List annotations = buf.toList(); + + return annotations; + } + + List typeAnnotationsOpt() { + List annotations = annotationsOpt(Tag.TYPE_ANNOTATION); + return annotations; } /** ModifiersOpt = { Modifier } @@ -2412,7 +2732,7 @@ if (token.deprecatedFlag()) { flags |= Flags.DEPRECATED; } - int lastPos = Position.NOPOS; + int lastPos; loop: while (true) { long flag; @@ -2439,12 +2759,11 @@ if (flag == Flags.ANNOTATION) { checkAnnotations(); if (token.kind != INTERFACE) { - JCAnnotation ann = annotation(lastPos); + JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION); // if first modifier is an annotation, set pos to annotation's. if (flags == 0 && annotations.isEmpty()) pos = ann.pos; annotations.append(ann); - lastPos = ann.pos; flag = 0; } } @@ -2468,14 +2787,27 @@ } /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] + * * @param pos position of "@" token + * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION */ - JCAnnotation annotation(int pos) { + JCAnnotation annotation(int pos, Tag kind) { // accept(AT); // AT consumed by caller checkAnnotations(); - JCTree ident = qualident(); + if (kind == Tag.TYPE_ANNOTATION) { + checkTypeAnnotations(); + } + JCTree ident = qualident(false); List fieldValues = annotationFieldValuesOpt(); - JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); + JCAnnotation ann; + if (kind == Tag.ANNOTATION) { + ann = F.at(pos).Annotation(ident, fieldValues); + } else if (kind == Tag.TYPE_ANNOTATION) { + ann = F.at(pos).TypeAnnotation(ident, fieldValues); + } else { + throw new AssertionError("Unhandled annotation kind: " + kind); + } + storeEnd(ann, S.prevToken().endPos); return ann; } @@ -2528,7 +2860,7 @@ case MONKEYS_AT: pos = token.pos; nextToken(); - return annotation(pos); + return annotation(pos, Tag.ANNOTATION); case LBRACE: pos = token.pos; accept(LBRACE); @@ -2683,7 +3015,7 @@ mods = null; } nextToken(); - pid = qualident(); + pid = qualident(false); accept(SEMI); } ListBuffer defs = new ListBuffer(); @@ -2934,7 +3266,7 @@ flags |= Flags.DEPRECATED; } int pos = token.pos; - List annotations = annotationsOpt(); + List annotations = annotationsOpt(Tag.ANNOTATION); JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); List typeArgs = typeArgumentsOpt(); int identPos = token.pos; @@ -3037,15 +3369,25 @@ mods.pos = pos; storeEnd(mods, pos); } + List annosAfterParams = annotationsOpt(Tag.ANNOTATION); + Token tk = token; pos = token.pos; JCExpression type; boolean isVoid = token.kind == VOID; if (isVoid) { + if (annosAfterParams.nonEmpty()) + illegal(annosAfterParams.head.pos); type = to(F.at(pos).TypeIdent(TypeTag.VOID)); nextToken(); } else { - type = parseType(); + if (annosAfterParams.nonEmpty()) { + mods.annotations = mods.annotations.appendList(annosAfterParams); + if (mods.pos == Position.NOPOS) + mods.pos = mods.annotations.head.pos; + } + // method returns types are un-annotated types + type = unannotatedType(); } if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) @@ -3101,51 +3443,68 @@ if (isInterface && (mods.flags & Flags.STATIC) != 0) { checkStaticInterfaceMethods(); } - List params = formalParameters(); - if (!isVoid) type = bracketsOpt(type); - List thrown = List.nil(); - if (token.kind == THROWS) { - nextToken(); - thrown = qualidentList(); - } - JCBlock body = null; - JCExpression defaultValue; - if (token.kind == LBRACE) { - body = block(); - defaultValue = null; - } else { - if (token.kind == DEFAULT) { - accept(DEFAULT); - defaultValue = annotationValue(); + JCVariableDecl prevReceiverParam = this.receiverParam; + try { + this.receiverParam = null; + // Parsing formalParameters sets the receiverParam, if present + List params = formalParameters(); + if (!isVoid) type = bracketsOpt(type); + List thrown = List.nil(); + if (token.kind == THROWS) { + nextToken(); + thrown = qualidentList(); + } + JCBlock body = null; + JCExpression defaultValue; + if (token.kind == LBRACE) { + body = block(); + defaultValue = null; } else { - defaultValue = null; - } - accept(SEMI); - if (token.pos <= endPosTable.errorEndPos) { - // error recovery - skip(false, true, false, false); - if (token.kind == LBRACE) { - body = block(); + if (token.kind == DEFAULT) { + accept(DEFAULT); + defaultValue = annotationValue(); + } else { + defaultValue = null; + } + accept(SEMI); + if (token.pos <= endPosTable.errorEndPos) { + // error recovery + skip(false, true, false, false); + if (token.kind == LBRACE) { + body = block(); + } } } + + JCMethodDecl result = + toP(F.at(pos).MethodDef(mods, name, type, typarams, + receiverParam, params, thrown, + body, defaultValue)); + attach(result, dc); + return result; + } finally { + this.receiverParam = prevReceiverParam; } - - JCMethodDecl result = - toP(F.at(pos).MethodDef(mods, name, type, typarams, - params, thrown, - body, defaultValue)); - attach(result, dc); - return result; } - /** QualidentList = Qualident {"," Qualident} + /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident} */ List qualidentList() { ListBuffer ts = new ListBuffer(); - ts.append(qualident()); + + List typeAnnos = typeAnnotationsOpt(); + if (!typeAnnos.isEmpty()) + ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true)))); + else + ts.append(qualident(true)); while (token.kind == COMMA) { nextToken(); - ts.append(qualident()); + + typeAnnos = typeAnnotationsOpt(); + if (!typeAnnos.isEmpty()) + ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true)))); + else + ts.append(qualident(true)); } return ts.toList(); } @@ -3174,13 +3533,14 @@ /** * {@literal - * TypeParameter = TypeVariable [TypeParameterBound] + * TypeParameter = [Annotations] TypeVariable [TypeParameterBound] * TypeParameterBound = EXTENDS Type {"&" Type} * TypeVariable = Ident * } */ JCTypeParameter typeParameter() { int pos = token.pos; + List annos = typeAnnotationsOpt(); Name name = ident(); ListBuffer bounds = new ListBuffer(); if (token.kind == EXTENDS) { @@ -3191,7 +3551,7 @@ bounds.append(parseType()); } } - return toP(F.at(pos).TypeParameter(name, bounds.toList())); + return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos)); } /** FormalParameters = "(" [ FormalParameterList ] ")" @@ -3203,10 +3563,17 @@ } List formalParameters(boolean lambdaParameters) { ListBuffer params = new ListBuffer(); - JCVariableDecl lastParam = null; + JCVariableDecl lastParam; accept(LPAREN); if (token.kind != RPAREN) { - params.append(lastParam = formalParameter(lambdaParameters)); + this.allowThisIdent = true; + lastParam = formalParameter(lambdaParameters); + if (lastParam.name.contentEquals(TokenKind.THIS.name)) { + this.receiverParam = lastParam; + } else { + params.append(lastParam); + } + this.allowThisIdent = false; while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { nextToken(); params.append(lastParam = formalParameter(lambdaParameters)); @@ -3241,6 +3608,77 @@ return mods; } + /** + * Inserts the annotations (and possibly a new array level) + * to the left-most type in an array or nested type. + * + * When parsing a type like {@code @B Outer.Inner @A []}, the + * {@code @A} annotation should target the array itself, while + * {@code @B} targets the nested type {@code Outer}. + * + * Currently the parser parses the annotation first, then + * the array, and then inserts the annotation to the left-most + * nested type. + * + * When {@code createNewLevel} is true, then a new array + * level is inserted as the most inner type, and have the + * annotations target it. This is useful in the case of + * varargs, e.g. {@code String @A [] @B ...}, as the parser + * first parses the type {@code String @A []} then inserts + * a new array level with {@code @B} annotation. + */ + private JCExpression insertAnnotationsToMostInner( + JCExpression type, List annos, + boolean createNewLevel) { + int origEndPos = getEndPos(type); + JCExpression mostInnerType = type; + JCArrayTypeTree mostInnerArrayType = null; + while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) { + mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType); + mostInnerType = mostInnerArrayType.elemtype; + } + + if (createNewLevel) { + mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType)); + } + + JCExpression mostInnerTypeToReturn = mostInnerType; + if (annos.nonEmpty()) { + JCExpression lastToModify = mostInnerType; + + while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) || + TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { + while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) { + lastToModify = mostInnerType; + mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression(); + } + while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { + lastToModify = mostInnerType; + mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz; + } + } + + mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType); + + if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) { + ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType; + } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) { + ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType; + } else { + // We never saw a SELECT or TYPEAPPLY, return the annotated type. + mostInnerTypeToReturn = mostInnerType; + } + } + + if (mostInnerArrayType == null) { + return mostInnerTypeToReturn; + } else { + mostInnerArrayType.elemtype = mostInnerTypeToReturn; + storeEnd(type, origEndPos); + return type; + } + } + /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter */ @@ -3249,12 +3687,27 @@ } protected JCVariableDecl formalParameter(boolean lambdaParameter) { JCModifiers mods = optFinal(Flags.PARAMETER); + // need to distinguish between vararg annos and array annos + // look at typeAnnotationsPushedBack comment + this.permitTypeAnnotationsPushBack = true; JCExpression type = parseType(); + this.permitTypeAnnotationsPushBack = false; + if (token.kind == ELLIPSIS) { + List varargsAnnos = typeAnnotationsPushedBack; + typeAnnotationsPushedBack = List.nil(); checkVarargs(); mods.flags |= Flags.VARARGS; - type = to(F.at(token.pos).TypeArray(type)); + // insert var arg type annotations + type = insertAnnotationsToMostInner(type, varargsAnnos, true); nextToken(); + } else { + // if not a var arg, then typeAnnotationsPushedBack should be null + if (typeAnnotationsPushedBack.nonEmpty()) { + reportSyntaxError(typeAnnotationsPushedBack.head.pos, + "illegal.start.of.type"); + } + typeAnnotationsPushedBack = List.nil(); } return variableDeclaratorId(mods, type, lambdaParameter); } @@ -3508,6 +3961,12 @@ allowStaticInterfaceMethods = true; } } + void checkTypeAnnotations() { + if (!allowTypeAnnotations) { + log.error(token.pos, "type.annotations.not.supported.in.source", source.name); + allowTypeAnnotations = true; + } + } /* * a functional source tree and end position mappings diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -59,6 +59,7 @@ private List savedTokens = new ArrayList(); private JavaTokenizer tokenizer; + /** * Create a scanner from the input array. This method might * modify the array. To avoid copying the input array, ensure diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -38,7 +38,7 @@ /** The char reader used by the javac lexer/tokenizer. Returns the sequence of * characters contained in the input stream, handling unicode escape accordingly. - * Additionally, it provide features for saving chars into a buffer and to retrieve + * Additionally, it provides features for saving chars into a buffer and to retrieve * them at a later stage. * *

This is NOT part of any supported API. diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -817,9 +817,6 @@ /** The set of package-info files to be processed this round. */ List packageInfoFiles; - /** The number of Messager errors generated in this round. */ - int nMessagerErrors; - /** Create a round (common code). */ private Round(Context context, int number, int priorErrors, int priorWarnings, Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { @@ -829,7 +826,7 @@ compiler = JavaCompiler.instance(context); log = Log.instance(context); log.nerrors = priorErrors; - log.nwarnings += priorWarnings; + log.nwarnings = priorWarnings; if (number == 1) { Assert.checkNonNull(deferredDiagnosticHandler); this.deferredDiagnosticHandler = deferredDiagnosticHandler; @@ -870,7 +867,7 @@ Set newSourceFiles, Map newClassFiles) { this(prev.nextContext(), prev.number+1, - prev.nMessagerErrors, + prev.compiler.log.nerrors, prev.compiler.log.nwarnings, null); this.genClassFiles = prev.genClassFiles; @@ -911,15 +908,12 @@ } /** Create the compiler to be used for the final compilation. */ - JavaCompiler finalCompiler(boolean errorStatus) { + JavaCompiler finalCompiler() { try { Context nextCtx = nextContext(); JavacProcessingEnvironment.this.context = nextCtx; JavaCompiler c = JavaCompiler.instance(nextCtx); - c.log.nwarnings += compiler.log.nwarnings; - if (errorStatus) { - c.log.nerrors += compiler.log.nerrors; - } + c.log.initRound(compiler.log); return c; } finally { compiler.close(false); @@ -1027,8 +1021,6 @@ if (!taskListener.isEmpty()) taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); } - - nMessagerErrors = messager.errorCount(); } void showDiagnostics(boolean showAll) { @@ -1107,9 +1099,7 @@ next.put(Tokens.tokensKey, tokens); Log nextLog = Log.instance(next); - // propogate the log's writers directly, instead of going through context - nextLog.setWriters(log); - nextLog.setSourceMap(log); + nextLog.initRound(log); JavaCompiler oldCompiler = JavaCompiler.instance(context); JavaCompiler nextCompiler = JavaCompiler.instance(next); @@ -1206,7 +1196,7 @@ new LinkedHashSet(filer.getGeneratedSourceFileObjects()); roots = cleanTrees(round.roots); - JavaCompiler compiler = round.finalCompiler(errorStatus); + JavaCompiler compiler = round.finalCompiler(); if (newSourceFiles.size() > 0) roots = roots.appendList(compiler.parseFiles(newSourceFiles)); @@ -1311,7 +1301,6 @@ if (procNames != null) return true; - String procPath; URL[] urls = new URL[1]; for(File pathElement : workingpath) { try { @@ -1382,6 +1371,10 @@ node.sym = null; super.visitIdent(node); } + public void visitAnnotation(JCAnnotation node) { + node.attribute = null; + super.visitAnnotation(node); + } }; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jan 23 13:27:24 2013 -0800 @@ -1666,6 +1666,9 @@ compiler.misc.bad.signature=\ bad signature: {0} +compiler.misc.bad.type.annotation.value=\ + bad type annotation target type value: {0} + compiler.misc.class.file.wrong.class=\ class file contains wrong class: {0} @@ -2149,6 +2152,23 @@ as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\ (use -source 1.3 or lower to use ''assert'' as an identifier) +# TODO 308: make a better error message +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 + +# 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 +compiler.err.cant.annotate.nested.type=\ + nested type cannot be annotated + +compiler.err.incorrect.receiver.type=\ + the receiver type does not match the enclosing class type + +compiler.err.no.annotations.on.dot.class=\ + no annotations are allowed in the type of a class literal + # 0: string compiler.err.generics.not.supported.in.source=\ generics are not supported in -source {0}\n\ @@ -2164,9 +2184,10 @@ annotations are not supported in -source {0}\n\ (use -source 5 or higher to enable annotations) -#308 compiler.err.type.annotations.not.supported.in.source=\ -#308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +# 0: string +compiler.err.type.annotations.not.supported.in.source=\ + type annotations are not supported in -source {0}\n\ +(use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=\ diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, 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 @@ -1340,6 +1340,10 @@ compiler.err.assert.as.identifier=\u30EA\u30EA\u30FC\u30B91.4\u304B\u3089''assert''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u3001\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''assert''\u3092\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001-source 1.3\u4EE5\u524D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) +# TODO 308: make a better error message +# 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: string compiler.err.generics.not.supported.in.source=\u7DCF\u79F0\u578B\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(\u7DCF\u79F0\u578B\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) @@ -1351,7 +1355,7 @@ #308 compiler.err.type.annotations.not.supported.in.source=\ #308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +#308 (use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=for-each\u30EB\u30FC\u30D7\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(for-each\u30EB\u30FC\u30D7\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, 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 @@ -1340,6 +1340,10 @@ compiler.err.assert.as.identifier=\u4ECE\u53D1\u884C\u7248 1.4 \u5F00\u59CB, ''assert'' \u662F\u4E00\u4E2A\u5173\u952E\u5B57, \u4F46\u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.3 \u6216\u66F4\u4F4E\u7248\u672C\u4EE5\u5C06 ''assert'' \u7528\u4F5C\u6807\u8BC6\u7B26) +# TODO 308: make a better error message +# 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: string compiler.err.generics.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301\u6CDB\u578B\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528\u6CDB\u578B) @@ -1351,7 +1355,7 @@ #308 compiler.err.type.annotations.not.supported.in.source=\ #308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +#308 (use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301 for-each \u5FAA\u73AF\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528 for-each \u5FAA\u73AF) diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -250,11 +250,11 @@ */ TYPEAPPLY, - /** Union types, of type TypeUnion + /** Union types, of type TypeUnion. */ TYPEUNION, - /** Intersection types, of type TypeIntersection + /** Intersection types, of type TypeIntersection. */ TYPEINTERSECTION, @@ -274,10 +274,16 @@ */ ANNOTATION, + /** metadata: Type annotation. + */ + TYPE_ANNOTATION, + /** metadata: Modifiers */ MODIFIERS, + /** An annotated type tree. + */ ANNOTATED_TYPE, /** Error trees, of type Erroneous. @@ -725,6 +731,8 @@ public JCExpression restype; /** type parameters */ public List typarams; + /** receiver parameter */ + public JCVariableDecl recvparam; /** value parameters */ public List params; /** exceptions thrown by this method */ @@ -739,6 +747,7 @@ Name name, JCExpression restype, List typarams, + JCVariableDecl recvparam, List params, List thrown, JCBlock body, @@ -750,6 +759,9 @@ this.restype = restype; this.typarams = typarams; this.params = params; + this.recvparam = recvparam; + // TODO: do something special if the given type is null? + // receiver != null ? receiver : List.nil()); this.thrown = thrown; this.body = body; this.defaultValue = defaultValue; @@ -768,6 +780,7 @@ public List getParameters() { return params; } + public JCVariableDecl getReceiverParameter() { return recvparam; } public List getThrows() { return thrown; } @@ -1505,6 +1518,10 @@ public static class JCNewArray extends JCExpression implements NewArrayTree { public JCExpression elemtype; public List dims; + // type annotations on inner-most component + public List annotations; + // type annotations on dimensions + public List> dimAnnotations; public List elems; protected JCNewArray(JCExpression elemtype, List dims, @@ -1512,6 +1529,8 @@ { this.elemtype = elemtype; this.dims = dims; + this.annotations = List.nil(); + this.dimAnnotations = List.nil(); this.elems = elems; } @Override @@ -2152,9 +2171,12 @@ public Name name; /** bounds */ public List bounds; - protected JCTypeParameter(Name name, List bounds) { + /** type annotations on type parameter */ + public List annotations; + protected JCTypeParameter(Name name, List bounds, List annotations) { this.name = name; this.bounds = bounds; + this.annotations = annotations; } @Override public void accept(Visitor v) { v.visitTypeParameter(this); } @@ -2164,6 +2186,9 @@ public List getBounds() { return bounds; } + public List getAnnotations() { + return annotations; + } @Override public R accept(TreeVisitor v, D d) { return v.visitTypeParameter(this, d); @@ -2230,16 +2255,27 @@ } public static class JCAnnotation extends JCExpression implements AnnotationTree { + // Either Tag.ANNOTATION or Tag.TYPE_ANNOTATION + private Tag tag; + public JCTree annotationType; public List args; - protected JCAnnotation(JCTree annotationType, List args) { + + // Attribute.Compound if tag is ANNOTATION + // Attribute.TypeCompound if tag is TYPE_ANNOTATION + public Attribute.Compound attribute; + + protected JCAnnotation(Tag tag, JCTree annotationType, List args) { + this.tag = tag; this.annotationType = annotationType; this.args = args; } + @Override public void accept(Visitor v) { v.visitAnnotation(this); } - public Kind getKind() { return Kind.ANNOTATION; } + public Kind getKind() { return TreeInfo.tagToKind(getTag()); } + public JCTree getAnnotationType() { return annotationType; } public List getArguments() { return args; @@ -2250,7 +2286,7 @@ } @Override public Tag getTag() { - return ANNOTATION; + return tag; } } @@ -2281,6 +2317,35 @@ } } + public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree { + // type annotations + public List annotations; + public JCExpression underlyingType; + + protected JCAnnotatedType(List annotations, JCExpression underlyingType) { + this.annotations = annotations; + this.underlyingType = underlyingType; + } + @Override + public void accept(Visitor v) { v.visitAnnotatedType(this); } + + public Kind getKind() { return Kind.ANNOTATED_TYPE; } + public List getAnnotations() { + return annotations; + } + public JCExpression getUnderlyingType() { + return underlyingType; + } + @Override + public R accept(TreeVisitor v, D d) { + return v.visitAnnotatedType(this, d); + } + @Override + public Tag getTag() { + return ANNOTATED_TYPE; + } + } + public static class JCErroneous extends JCExpression implements com.sun.source.tree.ErroneousTree { public List errs; @@ -2347,6 +2412,7 @@ Name name, JCExpression restype, List typarams, + JCVariableDecl recvparam, List params, List thrown, JCBlock body, @@ -2472,6 +2538,7 @@ public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); } public void visitAnnotation(JCAnnotation that) { visitTree(that); } public void visitModifiers(JCModifiers that) { visitTree(that); } + public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); } public void visitErroneous(JCErroneous that) { visitTree(that); } public void visitLetExpr(LetExpr that) { visitTree(that); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Wed Jan 23 13:27:24 2013 -0800 @@ -29,7 +29,6 @@ import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.tools.javac.code.*; -import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; @@ -261,6 +260,15 @@ } } + public void printTypeAnnotations(List trees) throws IOException { + if (trees.nonEmpty()) + print(" "); + for (List l = trees; l.nonEmpty(); l = l.tail) { + printExpr(l.head); + print(" "); + } + } + /** Print documentation comment, if it exists * @param tree The tree for which a documentation comment should be printed. */ @@ -491,6 +499,12 @@ print(" " + tree.name); } print("("); + if (tree.recvparam!=null) { + printExpr(tree.recvparam); + if (tree.params.size() > 0) { + print(", "); + } + } printExprs(tree.params); print(")"); if (tree.thrown.nonEmpty()) { @@ -543,7 +557,15 @@ } else { printExpr(tree.mods); if ((tree.mods.flags & VARARGS) != 0) { - printExpr(((JCArrayTypeTree) tree.vartype).elemtype); + JCTree vartype = tree.vartype; + List tas = null; + if (vartype instanceof JCAnnotatedType) { + tas = ((JCAnnotatedType)vartype).annotations; + vartype = ((JCAnnotatedType)vartype).underlyingType; + } + printExpr(((JCArrayTypeTree) vartype).elemtype); + if (tas != null) + printTypeAnnotations(tas); print("... " + tree.name); } else { printExpr(tree.vartype); @@ -919,16 +941,29 @@ try { if (tree.elemtype != null) { print("new "); + printTypeAnnotations(tree.annotations); JCTree elem = tree.elemtype; - if (elem.hasTag(TYPEARRAY)) - printBaseElementType((JCArrayTypeTree) elem); - else - printExpr(elem); + printBaseElementType(elem); + boolean isElemAnnoType = elem instanceof JCAnnotatedType; + int i = 0; + List> da = tree.dimAnnotations; for (List l = tree.dims; l.nonEmpty(); l = l.tail) { + if (da.size() > i) { + printTypeAnnotations(da.get(i)); + } print("["); + i++; printExpr(l.head); print("]"); } + if (tree.elems != null) { + if (isElemAnnoType) { + printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations); + } + print("[]"); + } + if (isElemAnnoType) + elem = ((JCAnnotatedType)elem).underlyingType; if (elem instanceof JCArrayTypeTree) printBrackets((JCArrayTypeTree) elem); } @@ -1225,6 +1260,12 @@ JCTree elem; while (true) { elem = tree.elemtype; + if (elem.hasTag(ANNOTATED_TYPE)) { + JCAnnotatedType atype = (JCAnnotatedType) elem; + elem = atype.underlyingType; + if (!elem.hasTag(TYPEARRAY)) break; + printTypeAnnotations(atype.annotations); + } print("[]"); if (!elem.hasTag(TYPEARRAY)) break; tree = (JCArrayTypeTree) elem; @@ -1327,6 +1368,32 @@ } } + public void visitAnnotatedType(JCAnnotatedType tree) { + try { + if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) { + JCFieldAccess access = (JCFieldAccess) tree.underlyingType; + printExpr(access.selected, TreeInfo.postfixPrec); + print("."); + printTypeAnnotations(tree.annotations); + print(access.name); + } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) { + JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType; + printBaseElementType(tree); + printTypeAnnotations(tree.annotations); + print("[]"); + JCExpression elem = array.elemtype; + if (elem.hasTag(TYPEARRAY)) { + printBrackets((JCArrayTypeTree) elem); + } + } else { + printTypeAnnotations(tree.annotations); + printExpr(tree.underlyingType); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitTree(JCTree tree) { try { print("(UNKNOWN: " + tree + ")"); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -71,11 +71,26 @@ return lb.toList(); } + public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) { + JCAnnotatedType t = (JCAnnotatedType) node; + List annotations = copy(t.annotations, p); + JCExpression underlyingType = copy(t.underlyingType, p); + return M.at(t.pos).AnnotatedType(annotations, underlyingType); + } + public JCTree visitAnnotation(AnnotationTree node, P p) { JCAnnotation t = (JCAnnotation) node; JCTree annotationType = copy(t.annotationType, p); List args = copy(t.args, p); - return M.at(t.pos).Annotation(annotationType, args); + if (t.getKind() == Tree.Kind.TYPE_ANNOTATION) { + JCAnnotation newTA = M.at(t.pos).TypeAnnotation(annotationType, args); + newTA.attribute = t.attribute; + return newTA; + } else { + JCAnnotation newT = M.at(t.pos).Annotation(annotationType, args); + newT.attribute = t.attribute; + return newT; + } } public JCTree visitAssert(AssertTree node, P p) { @@ -233,10 +248,11 @@ JCExpression restype = copy(t.restype, p); List typarams = copy(t.typarams, p); List params = copy(t.params, p); + JCVariableDecl recvparam = copy(t.recvparam, p); List thrown = copy(t.thrown, p); JCBlock body = copy(t.body, p); JCExpression defaultValue = copy(t.defaultValue, p); - return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, thrown, body, defaultValue); + return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, recvparam, params, thrown, body, defaultValue); } public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { @@ -384,8 +400,9 @@ public JCTree visitTypeParameter(TypeParameterTree node, P p) { JCTypeParameter t = (JCTypeParameter) node; + List annos = copy(t.annotations, p); List bounds = copy(t.bounds, p); - return M.at(t.pos).TypeParameter(t.name, bounds); + return M.at(t.pos).TypeParameter(t.name, bounds, annos); } public JCTree visitInstanceOf(InstanceOfTree node, P p) { diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -453,6 +453,19 @@ case POSTINC: case POSTDEC: return getStartPos(((JCUnary) tree).arg); + case ANNOTATED_TYPE: { + JCAnnotatedType node = (JCAnnotatedType) tree; + if (node.annotations.nonEmpty()) { + if (node.underlyingType.hasTag(TYPEARRAY) || + node.underlyingType.hasTag(SELECT)) { + return getStartPos(node.underlyingType); + } else { + return getStartPos(node.annotations.head); + } + } else { + return getStartPos(node.underlyingType); + } + } case NEWCLASS: { JCNewClass node = (JCNewClass)tree; if (node.encl != null) @@ -560,6 +573,8 @@ return getEndPos(((JCUnary) tree).arg, endPosTable); case WHILELOOP: return getEndPos(((JCWhileLoop) tree).body, endPosTable); + case ANNOTATED_TYPE: + return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) @@ -799,6 +814,8 @@ return ((JCFieldAccess) tree).sym; case TYPEAPPLY: return symbol(((JCTypeApply) tree).clazz); + case ANNOTATED_TYPE: + return symbol(((JCAnnotatedType) tree).underlyingType); default: return null; } @@ -1036,17 +1053,24 @@ case NULLCHK: return Tree.Kind.OTHER; + case ANNOTATION: + return Tree.Kind.ANNOTATION; + case TYPE_ANNOTATION: + return Tree.Kind.TYPE_ANNOTATION; + default: return null; } } /** - * Returns the underlying type of the tree if it is annotated type, - * or the tree itself otherwise + * Returns the underlying type of the tree if it is an annotated type, + * or the tree itself otherwise. */ public static JCExpression typeIn(JCExpression tree) { switch (tree.getTag()) { + case ANNOTATED_TYPE: + return ((JCAnnotatedType)tree).underlyingType; case IDENT: /* simple names */ case TYPEIDENT: /* primitive name */ case SELECT: /* qualified name */ @@ -1054,20 +1078,55 @@ case WILDCARD: /* wild cards */ case TYPEPARAMETER: /* type parameters */ case TYPEAPPLY: /* parameterized types */ + case ERRONEOUS: /* error tree TODO: needed for BadCast JSR308 test case. Better way? */ return tree; default: throw new AssertionError("Unexpected type tree: " + tree); } } + /* Return the inner-most type of a type tree. + * For an array that contains an annotated type, return that annotated type. + * TODO: currently only used by Pretty. Describe behavior better. + */ public static JCTree innermostType(JCTree type) { - switch (type.getTag()) { - case TYPEARRAY: - return innermostType(((JCArrayTypeTree)type).elemtype); - case WILDCARD: - return innermostType(((JCWildcard)type).inner); - default: - return type; + JCTree lastAnnotatedType = null; + JCTree cur = type; + loop: while (true) { + switch (cur.getTag()) { + case TYPEARRAY: + lastAnnotatedType = null; + cur = ((JCArrayTypeTree)cur).elemtype; + break; + case WILDCARD: + lastAnnotatedType = null; + cur = ((JCWildcard)cur).inner; + break; + case ANNOTATED_TYPE: + lastAnnotatedType = cur; + cur = ((JCAnnotatedType)cur).underlyingType; + break; + default: + break loop; + } + } + if (lastAnnotatedType!=null) { + return lastAnnotatedType; + } else { + return cur; } } + + private static class TypeAnnotationFinder extends TreeScanner { + public boolean foundTypeAnno = false; + public void visitAnnotation(JCAnnotation tree) { + foundTypeAnno = foundTypeAnno || tree.hasTag(TYPE_ANNOTATION); + } + } + + public static boolean containsTypeAnnotation(JCTree e) { + TypeAnnotationFinder finder = new TypeAnnotationFinder(); + finder.scan(e); + return finder.foundTypeAnno; + } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -169,10 +169,26 @@ List thrown, JCBlock body, JCExpression defaultValue) { + return MethodDef( + mods, name, restype, typarams, null, params, + thrown, body, defaultValue); + } + + public JCMethodDecl MethodDef(JCModifiers mods, + Name name, + JCExpression restype, + List typarams, + JCVariableDecl recvparam, + List params, + List thrown, + JCBlock body, + JCExpression defaultValue) + { JCMethodDecl tree = new JCMethodDecl(mods, name, restype, typarams, + recvparam, params, thrown, body, @@ -463,7 +479,11 @@ } public JCTypeParameter TypeParameter(Name name, List bounds) { - JCTypeParameter tree = new JCTypeParameter(name, bounds); + return TypeParameter(name, bounds, List.nil()); + } + + public JCTypeParameter TypeParameter(Name name, List bounds, List annos) { + JCTypeParameter tree = new JCTypeParameter(name, bounds, annos); tree.pos = pos; return tree; } @@ -481,7 +501,13 @@ } public JCAnnotation Annotation(JCTree annotationType, List args) { - JCAnnotation tree = new JCAnnotation(annotationType, args); + JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args); + tree.pos = pos; + return tree; + } + + public JCAnnotation TypeAnnotation(JCTree annotationType, List args) { + JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args); tree.pos = pos; return tree; } @@ -497,6 +523,12 @@ return Modifiers(flags, List.nil()); } + public JCAnnotatedType AnnotatedType(List annotations, JCExpression underlyingType) { + JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType); + tree.pos = pos; + return tree; + } + public JCErroneous Erroneous() { return Erroneous(List.nil()); } @@ -755,7 +787,11 @@ result = Erroneous(); } public void visitCompound(Attribute.Compound compound) { - result = visitCompoundInternal(compound); + if (compound instanceof Attribute.TypeCompound) { + result = visitTypeCompoundInternal((Attribute.TypeCompound) compound); + } else { + result = visitCompoundInternal(compound); + } } public JCAnnotation visitCompoundInternal(Attribute.Compound compound) { ListBuffer args = new ListBuffer(); @@ -766,6 +802,15 @@ } return Annotation(Type(compound.type), args.toList()); } + public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) { + ListBuffer args = new ListBuffer(); + for (List> values = compound.values; values.nonEmpty(); values=values.tail) { + Pair pair = values.head; + JCExpression valueTree = translate(pair.snd); + args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); + } + return TypeAnnotation(Type(compound.type), args.toList()); + } public void visitArray(Attribute.Array array) { ListBuffer elems = new ListBuffer(); for (int i = 0; i < array.values.length; i++) @@ -779,7 +824,11 @@ JCAnnotation translate(Attribute.Compound a) { return visitCompoundInternal(a); } + JCAnnotation translate(Attribute.TypeCompound a) { + return visitTypeCompoundInternal(a); + } } + AnnotationBuilder annotationBuilder = new AnnotationBuilder(); /** Create an annotation tree from an attribute. @@ -788,6 +837,10 @@ return annotationBuilder.translate((Attribute.Compound)a); } + public JCAnnotation TypeAnnotation(Attribute a) { + return annotationBuilder.translate((Attribute.TypeCompound) a); + } + /** Create a method definition from a method symbol and a method body. */ public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) { @@ -804,6 +857,7 @@ m.name, Type(mtype.getReturnType()), TypeParams(mtype.getTypeArguments()), + null, // receiver type Params(mtype.getParameterTypes(), m), Types(mtype.getThrownTypes()), body, @@ -822,7 +876,6 @@ */ public List TypeParams(List typarams) { ListBuffer tparams = new ListBuffer(); - int i = 0; for (List l = typarams; l.nonEmpty(); l = l.tail) tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head)); return tparams.toList(); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, 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 @@ -84,6 +84,7 @@ scan(tree.mods); scan(tree.restype); scan(tree.typarams); + scan(tree.recvparam); scan(tree.params); scan(tree.thrown); scan(tree.defaultValue); @@ -200,15 +201,18 @@ public void visitNewClass(JCNewClass tree) { scan(tree.encl); + scan(tree.typeargs); scan(tree.clazz); - scan(tree.typeargs); scan(tree.args); scan(tree.def); } public void visitNewArray(JCNewArray tree) { + scan(tree.annotations); scan(tree.elemtype); scan(tree.dims); + for (List annos : tree.dimAnnotations) + scan(annos); scan(tree.elems); } @@ -291,6 +295,7 @@ } public void visitTypeParameter(JCTypeParameter tree) { + scan(tree.annotations); scan(tree.bounds); } @@ -314,6 +319,11 @@ scan(tree.args); } + public void visitAnnotatedType(JCAnnotatedType tree) { + scan(tree.annotations); + scan(tree.underlyingType); + } + public void visitErroneous(JCErroneous tree) { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, 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 @@ -139,6 +139,7 @@ tree.mods = translate(tree.mods); tree.restype = translate(tree.restype); tree.typarams = translateTypeParams(tree.typarams); + tree.recvparam = translate(tree.recvparam); tree.params = translateVarDefs(tree.params); tree.thrown = translate(tree.thrown); tree.body = translate(tree.body); @@ -289,6 +290,11 @@ } public void visitNewArray(JCNewArray tree) { + tree.annotations = translate(tree.annotations); + List> dimAnnos = List.nil(); + for (List origDimAnnos : tree.dimAnnotations) + dimAnnos = dimAnnos.append(translate(origDimAnnos)); + tree.dimAnnotations = dimAnnos; tree.elemtype = translate(tree.elemtype); tree.dims = translate(tree.dims); tree.elems = translate(tree.elems); @@ -385,6 +391,7 @@ } public void visitTypeParameter(JCTypeParameter tree) { + tree.annotations = translate(tree.annotations); tree.bounds = translate(tree.bounds); result = tree; } @@ -422,6 +429,12 @@ result = tree; } + public void visitAnnotatedType(JCAnnotatedType tree) { + tree.annotations = translate(tree.annotations); + tree.underlyingType = translate(tree.underlyingType); + result = tree; + } + public void visitTree(JCTree tree) { throw new AssertionError(tree); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -388,7 +388,7 @@ this.source = source; this.position = pos; this.key = key; - this.args = args; + this.args = args; int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition()); if (n == Position.NOPOS || source == null) diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -217,7 +217,7 @@ private JavacMessages messages; /** -+ * Handler for initial dispatch of diagnostics. + * Handler for initial dispatch of diagnostics. */ private DiagnosticHandler diagnosticHandler; @@ -385,14 +385,17 @@ noticeWriter = warnWriter = errWriter = pw; } - public void setWriters(Log other) { + /** + * Propagate the previous log's information. + */ + public void initRound(Log other) { this.noticeWriter = other.noticeWriter; this.warnWriter = other.warnWriter; this.errWriter = other.errWriter; - } - - public void setSourceMap(Log other) { this.sourceMap = other.sourceMap; + this.recorded = other.recorded; + this.nerrors = other.nerrors; + this.nwarnings = other.nwarnings; } /** diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -104,4 +104,8 @@ public AnnotationTypeDoc asAnnotationTypeDoc() { return null; } + + public AnnotatedType asAnnotatedType() { + return null; + } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,125 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javadoc; + +import com.sun.javadoc.*; +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; +import com.sun.tools.javac.util.List; + +/** + * Implementation of AnnotatedType, which + * represents an annotated type. + * + * @author Mahmood Ali + * @since 1.8 + */ +public class AnnotatedTypeImpl + extends AbstractTypeImpl implements AnnotatedType { + + AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) { + super(env, type); + } + + /** + * Get the annotations of this program element. + * Return an empty array if there are none. + */ + @Override + public AnnotationDesc[] annotations() { + List tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations; + if (tas == null || + tas.isEmpty()) { + return new AnnotationDesc[0]; + } + AnnotationDesc res[] = new AnnotationDesc[tas.length()]; + int i = 0; + for (Attribute.Compound a : tas) { + res[i++] = new AnnotationDescImpl(env, a); + } + return res; + } + + @Override + public com.sun.javadoc.Type underlyingType() { + return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false); + } + + @Override + public AnnotatedType asAnnotatedType() { + return this; + } + + @Override + public String toString() { + return typeName(); + } + + @Override + public String typeName() { + return this.underlyingType().typeName(); + } + + @Override + public String qualifiedTypeName() { + return this.underlyingType().qualifiedTypeName(); + } + + @Override + public String simpleTypeName() { + return this.underlyingType().simpleTypeName(); + } + + @Override + public String dimension() { + return this.underlyingType().dimension(); + } + + @Override + public boolean isPrimitive() { + return this.underlyingType().isPrimitive(); + } + + @Override + public ClassDoc asClassDoc() { + return this.underlyingType().asClassDoc(); + } + + @Override + public TypeVariable asTypeVariable() { + return this.underlyingType().asTypeVariable(); + } + + @Override + public WildcardType asWildcardType() { + return this.underlyingType().asWildcardType(); + } + + @Override + public ParameterizedType asParameterizedType() { + return this.underlyingType().asParameterizedType(); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1186,6 +1186,13 @@ } /** + * Returns null, as this is not an annotated type. + */ + public AnnotatedType asAnnotatedType() { + return null; + } + + /** * Return false, as this is not a primitive type. */ public boolean isPrimitive() { diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,10 +28,14 @@ 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; @@ -195,6 +199,24 @@ return result; } + public AnnotationDesc[] receiverAnnotations() { + // TODO: change how receiver annotations are output! + Type recvtype = sym.type.asMethodType().recvtype; + if (recvtype == null) { + return new AnnotationDesc[0]; + } + if (recvtype.getKind() != TypeKind.ANNOTATED) { + return new AnnotationDesc[0]; + } + List typeAnnos = ((com.sun.tools.javac.code.Type.AnnotatedType)recvtype).typeAnnotations; + AnnotationDesc result[] = new AnnotationDesc[typeAnnos.length()]; + int i = 0; + for (Attribute.Compound a : typeAnnos) { + result[i++] = new AnnotationDescImpl(env, a); + } + return result; + } + /** * Return the formal type parameters of this method or constructor. * Return an empty array if there are none. diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -121,13 +121,20 @@ } /** - * Return null, as this is not a wildcard type; + * Return null, as this is not a wildcard type. */ public WildcardType asWildcardType() { return null; } /** + * Return null, as this is not an annotated type. + */ + public AnnotatedType asAnnotatedType() { + return null; + } + + /** * Returns a string representation of the type. * * Return name of type including any dimension information. diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,6 +25,8 @@ 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; @@ -51,12 +53,27 @@ * @param errToClassDoc if true, ERROR type results in a ClassDoc; * false preserves legacy behavior */ + public static com.sun.javadoc.Type getType(DocEnv env, Type t, + boolean errorToClassDoc) { + return getType(env, t, errorToClassDoc, true); + } + @SuppressWarnings("fallthrough") public static com.sun.javadoc.Type getType(DocEnv env, Type t, - boolean errToClassDoc) { + boolean errToClassDoc, boolean considerAnnotations) { if (env.legacyDoclet) { t = env.types.erasure(t); } + if (considerAnnotations + && t.getKind() == TypeKind.ANNOTATED) { + return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t); + } + + if (t.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType at = (Type.AnnotatedType) t; + return new AnnotatedTypeImpl(env, at); + } + switch (t.getTag()) { case CLASS: if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) { @@ -129,6 +146,11 @@ * Class names are qualified if "full" is true. */ static String getTypeString(DocEnv env, Type t, boolean full) { + // TODO: should annotations be included here? + if (t.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType at = (Type.AnnotatedType)t; + t = at.underlyingType; + } switch (t.getTag()) { case ARRAY: StringBuilder s = new StringBuilder(); @@ -282,6 +304,13 @@ } /** + * Return null, as there are no annotations of the type + */ + public AnnotatedType asAnnotatedType() { + return null; + } + + /** * Return this type as an AnnotationTypeDoc if it * represents an annotation type. Array dimensions are ignored. */ diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -25,8 +25,12 @@ package com.sun.tools.javadoc; +import javax.lang.model.type.TypeKind; + import com.sun.javadoc.*; +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; @@ -120,11 +124,30 @@ * Get the bounds of a type variable as listed in the "extends" clause. */ private static List getBounds(TypeVar v, DocEnv env) { - Name boundname = v.getUpperBound().tsym.getQualifiedName(); - if (boundname == boundname.table.names.java_lang_Object) { + final Type upperBound = v.getUpperBound(); + Name boundname = upperBound.tsym.getQualifiedName(); + if (boundname == boundname.table.names.java_lang_Object + && upperBound.getKind() != TypeKind.ANNOTATED) { return List.nil(); } else { return env.types.getBounds(v); } } + + /** + * Get the annotations of this program element. + * Return an empty array if there are none. + */ + public AnnotationDesc[] annotations() { + if (type.getKind() != TypeKind.ANNOTATED) { + return new AnnotationDesc[0]; + } + List tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations; + AnnotationDesc res[] = new AnnotationDesc[tas.length()]; + int i = 0; + for (Attribute.Compound a : tas) { + res[i++] = new AnnotationDescImpl(env, a); + } + return res; + } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,6 +26,7 @@ package com.sun.tools.javap; import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.TypeAnnotation; import com.sun.tools.classfile.Annotation.Annotation_element_value; import com.sun.tools.classfile.Annotation.Array_element_value; import com.sun.tools.classfile.Annotation.Class_element_value; @@ -76,6 +77,124 @@ print(")"); } + public void write(TypeAnnotation annot) { + write(annot, true, false); + } + + public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) { + write(annot.annotation, resolveIndices); + print(": "); + write(annot.position, showOffsets); + } + + public void write(TypeAnnotation.Position pos, boolean showOffsets) { + print(pos.type); + + switch (pos.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + if (pos.lvarOffset == null) { + print(", lvarOffset is Null!"); + break; + } + print(", {"); + for (int i = 0; i < pos.lvarOffset.length; ++i) { + if (i != 0) print("; "); + if (showOffsets) { + print("start_pc="); + print(pos.lvarOffset[i]); + } + print(", length="); + print(pos.lvarLength[i]); + print(", index="); + print(pos.lvarIndex[i]); + } + print("}"); + break; + // exception parameter + case EXCEPTION_PARAMETER: + print(", exception_index="); + print(pos.exception_index); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + print(", param_index="); + print(pos.parameter_index); + print(", bound_index="); + print(pos.bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + print(", type_index="); + print(pos.type_index); + break; + // throws + case THROWS: + print(", type_index="); + print(pos.type_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + print(", type_index="); + print(pos.type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + case UNKNOWN: + throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos); + } + + // Append location data for generics/arrays. + if (!pos.location.isEmpty()) { + print(", location="); + print(pos.location); + } + } + public void write(Annotation.element_value_pair pair) { write(pair, false); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -49,8 +49,10 @@ import com.sun.tools.classfile.MethodParameters_attribute; import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; import com.sun.tools.classfile.Signature_attribute; import com.sun.tools.classfile.SourceDebugExtension_attribute; import com.sun.tools.classfile.SourceFile_attribute; @@ -433,6 +435,30 @@ return null; } + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { + println("RuntimeVisibleTypeAnnotations:"); + indent(+1); + for (int i = 0; i < attr.annotations.length; i++) { + print(i + ": "); + annotationWriter.write(attr.annotations[i]); + println(); + } + indent(-1); + return null; + } + + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { + println("RuntimeInvisibleTypeAnnotations:"); + indent(+1); + for (int i = 0; i < attr.annotations.length; i++) { + print(i + ": "); + annotationWriter.write(attr.annotations[i]); + println(); + } + indent(-1); + return null; + } + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { println("RuntimeVisibleParameterAnnotations:"); indent(+1); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -64,6 +64,7 @@ stackMapWriter = StackMapWriter.instance(context); localVariableTableWriter = LocalVariableTableWriter.instance(context); localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context); + typeAnnotationWriter = TypeAnnotationWriter.instance(context); options = Options.instance(context); } @@ -265,6 +266,11 @@ detailWriters.add(tryBlockWriter); } + if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) { + typeAnnotationWriter.reset(attr); + detailWriters.add(typeAnnotationWriter); + } + return detailWriters; } @@ -273,6 +279,7 @@ private ConstantWriter constantWriter; private LocalVariableTableWriter localVariableTableWriter; private LocalVariableTypeTableWriter localVariableTypeTableWriter; + private TypeAnnotationWriter typeAnnotationWriter; private SourceWriter sourceWriter; private StackMapWriter stackMapWriter; private TryBlockWriter tryBlockWriter; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java --- a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, 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 @@ -42,10 +42,13 @@ LOCAL_VAR_TYPES("localVariableTypes"), SOURCE("source"), STACKMAPS("stackMaps"), - TRY_BLOCKS("tryBlocks"); + TRY_BLOCKS("tryBlocks"), + TYPE_ANNOS("typeAnnotations"); + Kind(String option) { this.option = option; } + final String option; } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,126 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.javap; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.TypeAnnotation.Position; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Annotate instructions with details about type annotations. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class TypeAnnotationWriter extends InstructionDetailWriter { + public enum NoteKind { VISIBLE, INVISIBLE }; + public static class Note { + Note(NoteKind kind, TypeAnnotation anno) { + this.kind = kind; + this.anno = anno; + } + public final NoteKind kind; + public final TypeAnnotation anno; + } + + static TypeAnnotationWriter instance(Context context) { + TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class); + if (instance == null) + instance = new TypeAnnotationWriter(context); + return instance; + } + + protected TypeAnnotationWriter(Context context) { + super(context); + context.put(TypeAnnotationWriter.class, this); + annotationWriter = AnnotationWriter.instance(context); + classWriter = ClassWriter.instance(context); + } + + public void reset(Code_attribute attr) { + Method m = classWriter.getMethod(); + pcMap = new HashMap>(); + check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations)); + check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations)); + } + + private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) { + if (attr == null) + return; + + for (TypeAnnotation anno: attr.annotations) { + Position p = anno.position; + Note note = null; + if (p.offset != -1) + addNote(p.offset, note = new Note(kind, anno)); + if (p.lvarOffset != null) { + for (int i = 0; i < p.lvarOffset.length; i++) { + if (note == null) + note = new Note(kind, anno); + addNote(p.lvarOffset[i], note); + } + } + } + } + + private void addNote(int pc, Note note) { + List list = pcMap.get(pc); + if (list == null) + pcMap.put(pc, list = new ArrayList()); + list.add(note); + } + + @Override + void writeDetails(Instruction instr) { + String indent = space(2); // get from Options? + int pc = instr.getPC(); + List notes = pcMap.get(pc); + if (notes != null) { + for (Note n: notes) { + print(indent); + print("@"); + annotationWriter.write(n.anno, false, true); + print(", "); + println(n.kind.toString().toLowerCase()); + } + } + } + + private AnnotationWriter annotationWriter; + private ClassWriter classWriter; + private Map> pcMap; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/SourceVersion.java --- a/langtools/src/share/classes/javax/lang/model/SourceVersion.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/SourceVersion.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -46,7 +46,7 @@ */ public enum SourceVersion { /* - * Summary of language evoluation + * Summary of language evolution * 1.1: nested classes * 1.2: strictfp * 1.3: no changes diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,48 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.lang.model.type; + +import java.util.List; + +import javax.lang.model.element.AnnotationMirror; + +/** + * Represents an annotated type. + * + * As of the {@link javax.lang.model.SourceVersion#RELEASE_8 + * RELEASE_8} source version, annotated types can appear for all + * type uses. + * + * @author Werner Dietl + * @since 1.8 + */ +public interface AnnotatedType extends TypeMirror, + DeclaredType, TypeVariable, WildcardType, + PrimitiveType, ArrayType { + + List getAnnotations(); + TypeMirror getUnderlyingType(); +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/type/ExecutableType.java --- a/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -78,6 +78,14 @@ List getParameterTypes(); /** + * Returns the type of this executable's receiver parameter. + * + * @return the type of this executable's receiver parameter + * TODO: null if none specified or always a valid value? + */ + TypeMirror getReceiverType(); + + /** * Returns the exceptions and other throwables listed in this * executable's {@code throws} clause. * diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/type/TypeKind.java --- a/langtools/src/share/classes/javax/lang/model/type/TypeKind.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/type/TypeKind.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -151,7 +151,14 @@ * * @since 1.8 */ - INTERSECTION; + INTERSECTION, + + /** + * An annotated type. + * + * @since 1.8 + */ + ANNOTATED; /** * Returns {@code true} if this kind corresponds to a primitive diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java --- a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -182,4 +182,14 @@ * @since 1.8 */ R visitIntersection(IntersectionType t, P p); + + /** + * Visits an annotated type. + * + * @param t the type to visit + * @param p a visitor-specified parameter + * @return a visitor-specified result + * @since 1.8 + */ + R visitAnnotated(AnnotatedType t, P p); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java --- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -125,6 +125,23 @@ } /** + * Visits an {@code AnnotatedType} element by calling {@code + * visit} on the underlying type. + + * @param t {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of calling {@code visit} on the underlying type + * + * @since 1.8 + * + * TODO: should xxxVisitor8 subclasses override this and call + * the defaultAction? + */ + public R visitAnnotated(AnnotatedType t, P p) { + return visit(t.getUnderlyingType(), p); + } + + /** * {@inheritDoc} * *

The default implementation of this method in {@code diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/src/share/classes/javax/lang/model/util/Types.java --- a/langtools/src/share/classes/javax/lang/model/util/Types.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/src/share/classes/javax/lang/model/util/Types.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,6 +25,9 @@ package javax.lang.model.util; +import java.lang.annotation.Annotation; +import java.lang.annotation.AnnotationTypeMismatchException; +import java.lang.annotation.IncompleteAnnotationException; import java.util.List; import javax.lang.model.element.*; import javax.lang.model.type.*; @@ -298,4 +301,116 @@ * for the given type */ TypeMirror asMemberOf(DeclaredType containing, Element element); + + /** + * Returns the annotations targeting the type. + * + * @param type the targeted type + * @return the type annotations targeting the type + */ + List typeAnnotationsOf(TypeMirror type); + + /** + * Returns the type's annotation for the specified type if + * such an annotation is present, else {@code null}. The + * annotation has to be directly present on this + * element. + * + *

The annotation returned by this method could contain an element + * whose value is of type {@code Class}. + * This value cannot be returned directly: information necessary to + * locate and load a class (such as the class loader to use) is + * not available, and the class might not be loadable at all. + * Attempting to read a {@code Class} object by invoking the relevant + * method on the returned annotation + * will result in a {@link MirroredTypeException}, + * from which the corresponding {@link TypeMirror} may be extracted. + * Similarly, attempting to read a {@code Class[]}-valued element + * will result in a {@link MirroredTypesException}. + * + *

+ * Note: This method is unlike others in this and related + * interfaces. It operates on runtime reflective information — + * representations of annotation types currently loaded into the + * VM — rather than on the representations defined by and used + * throughout these interfaces. Consequently, calling methods on + * the returned annotation object can throw many of the exceptions + * that can be thrown when calling methods on an annotation object + * returned by core reflection. This method is intended for + * callers that are written to operate on a known, fixed set of + * annotation types. + *
+ * + * @param the annotation type + * @param type the targeted type + * @param annotationType the {@code Class} object corresponding to + * the annotation type + * @return the type's annotation for the specified annotation + * type if present on the type, else {@code null} + * + * @see Element#getAnnotationMirrors() + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + */ + A typeAnnotationOf(TypeMirror type, Class annotationType); + + /** + * Returns the annotations targeting the method receiver type. + * + * @param type the targeted type + * @return the receiver type of the executable type + */ + TypeMirror receiverTypeOf(ExecutableType type); + + /** + * Returns the type's annotation for the specified executable type + * receiver if such an annotation is present, else {@code null}. The + * annotation has to be directly present on this + * element. + * + *

The annotation returned by this method could contain an element + * whose value is of type {@code Class}. + * This value cannot be returned directly: information necessary to + * locate and load a class (such as the class loader to use) is + * not available, and the class might not be loadable at all. + * Attempting to read a {@code Class} object by invoking the relevant + * method on the returned annotation + * will result in a {@link MirroredTypeException}, + * from which the corresponding {@link TypeMirror} may be extracted. + * Similarly, attempting to read a {@code Class[]}-valued element + * will result in a {@link MirroredTypesException}. + * + *

+ * Note: This method is unlike others in this and related + * interfaces. It operates on runtime reflective information — + * representations of annotation types currently loaded into the + * VM — rather than on the representations defined by and used + * throughout these interfaces. Consequently, calling methods on + * the returned annotation object can throw many of the exceptions + * that can be thrown when calling methods on an annotation object + * returned by core reflection. This method is intended for + * callers that are written to operate on a known, fixed set of + * annotation types. + *
+ * + * @param
the annotation type + * @param type the method type + * @param annotationType the {@code Class} object corresponding to + * the annotation type + * @return the type's annotation for the specified annotation + * type if present on the type, else {@code null} + * + * @see Element#getAnnotationMirrors() + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + */ + // TODO: no longer needed? + // A receiverTypeAnnotationOf(ExecutableType type, Class annotationType); + } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009 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 Make sure that annotations types with optional elements has + * element headers + * @author Mahmood Ali + * @library ../lib/ + * @build JavadocTester + * @build TestAnnotationOptional + * @run main TestAnnotationOptional + */ + +public class TestAnnotationOptional extends JavadocTester { + + //Test information. + private static final String BUG_ID = "NO_BUG_ID_YET"; + + //Javadoc arguments. + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-sourcepath", SRC_DIR, "-source", "1.5", "pkg" + }; + + //Input for string search tests. + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "AnnotationOptional.html", + "" + } + }; + + private static final String[][] NEGATED_TEST = NO_TEST; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestAnnotationOptional tester = new TestAnnotationOptional(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009 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. + */ + +package pkg; + +import java.lang.annotation.*; + +/** + * This is just a test annotation type with optional value element. + * + * @author Mahmood Ali + * @since 1.5 + */ +@Documented public @interface AnnotationOptional { + String value() default ""; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2010 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 8006735 + * @ignore + * @summary Smoke test for ensuring that annotations are emited to javadoc + * + * @author Mahmood Ali + * @library ../../lib/ + * @build JavadocTester + * @build TestSmoke + * @run main TestSmoke + */ + +public class TestSmoke extends JavadocTester { + + //Test information. + private static final String BUG_ID = "NOT_SPECIFIED_YET"; + + //Javadoc arguments. + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" + }; + + //Input for string search tests. + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x22.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"}, + {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@DA"} + }; + + private static final String[][] NEGATED_TEST = { + {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x00.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x01.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x02.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x04.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x08.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@A"}, + {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 + "T0x22.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"}, + {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@A"} + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestSmoke tester = new TestSmoke(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2010 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. + */ + +package pkg; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.util.*; +import java.io.*; + +/* + * @summary compiler accepts all values + * @author Mahmood Ali + * @author Yuri Gaevsky + */ + +@Target({TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +@Target({TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@interface DA {} + +/** wildcard bound */ +class T0x1C { + void m0x1C(List lst) {} +} + +/** wildcard bound generic/array */ +class T0x1D { + void m0x1D(List> lst) {} +} + +/** typecast */ +class T0x00 { + void m0x00(Long l1) { + Object l2 = (@A @DA Long) l1; + } +} + +/** typecast generic/array */ +class T0x01 { + void m0x01(List list) { + List l = (List<@A @DA T>) list; + } +} + +/** instanceof */ +class T0x02 { + boolean m0x02(String s) { + return (s instanceof @A @DA String); + } +} + +/** object creation (new) */ +class T0x04 { + void m0x04() { + new @A @DA ArrayList(); + } +} + +/** local variable */ +class T0x08 { + void m0x08() { + @A @DA String s = null; + } +} + +/** 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 { + <@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 { +} + +class T0x10A { +} + +/** method type parameter bound */ +class T0x12 { + void m0x12() {} +} + +/** class type parameter bound generic/array */ +class T0x11> { +} + +/** method type parameter bound generic/array */ +class T0x13 { + static > T m0x13() { + return null; + } +} + +/** class extends/implements generic/array */ +class T0x15 extends ArrayList<@A @DA T> { +} + +/** type test (instanceof) generic/array */ +class T0x03 { + void m0x03(T typeObj, Object obj) { + boolean ok = obj instanceof String @A @DA []; + } +} + +/** object creation (new) generic/array */ +class T0x05 { + void m0x05() { + new ArrayList<@A @DA T>(); + } +} + +/** local variable generic/array */ +class T0x09 { + void g() { + List<@A @DA String> l = null; + } + + void a() { + String @A @DA [] as = null; + } +} + +/** type argument in constructor call generic/array */ +class T0x19 { + T0x19() {} + + void g() { + new > T0x19(); + } +} + +/** type argument in method call generic/array */ +class T0x1B { + void m0x1B() { + Collections.emptyList(); + } +} + +/** type argument in constructor call */ +class T0x18 { + T0x18() {} + + void m() { + new <@A @DA Integer> T0x18(); + } +} + +/** type argument in method call */ +class T0x1A { + public static T m() { return null; } + static void m0x1A() { + T0x1A.<@A @DA Integer, @A @DA Short>m(); + } +} + +/** class extends/implements */ +class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable { +} + +/** exception type in throws */ +class T0x16 { + void m0x16() throws @A @DA Exception {} +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/7129225/TestImportStar.java --- a/langtools/test/tools/javac/7129225/TestImportStar.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/7129225/TestImportStar.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -30,7 +30,7 @@ * @build JavacTestingAbstractProcessor * @compile/fail/ref=NegTest.ref -XDrawDiagnostics TestImportStar.java * @compile Anno.java AnnoProcessor.java - * @compile/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java + * @compile/fail/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java */ //The @compile/fail... verifies that the fix doesn't break the normal compilation of import xxx.* diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/7129225/TestImportStar.ref --- a/langtools/test/tools/javac/7129225/TestImportStar.ref Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/7129225/TestImportStar.ref Wed Jan 23 13:27:24 2013 -0800 @@ -1,3 +1,4 @@ - compiler.note.proc.messager: RUNNING - lastRound = false TestImportStar.java:39:1: compiler.err.doesnt.exist: xxx - compiler.note.proc.messager: RUNNING - lastRound = true +1 error \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/T6873845.java --- a/langtools/test/tools/javac/T6873845.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/T6873845.java Wed Jan 23 13:27:24 2013 -0800 @@ -19,8 +19,8 @@ if (out.contains("sunapi")) throw new Exception("unexpected output for -X"); - String warn1 = "T6873845.java:72:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; - String warn2 = "T6873845.java:77:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String warn1 = "T6873845.java:73:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String warn2 = "T6873845.java:78:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; String note1 = "- compiler.note.sunapi.filename: T6873845.java" + newline; String note2 = "- compiler.note.sunapi.recompile" + newline; @@ -52,7 +52,8 @@ args.add(0, "-XDrawDiagnostics"); String out = compile(args); if (!out.equals(expect)) - throw new Exception("unexpected output from compiler"); + throw new Exception("unexpected output from compiler; expected: " + expect + + "\n found: " + out); } String compile(List args) throws Exception{ diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/T6985181.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T6985181.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,88 @@ +/* + * 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 + * 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 6985181 + * @summary Annotations lost from classfile + */ + +import java.io.*; +import java.util.*; + +public class T6985181 { + public static void main(String... args) throws Exception{ + new T6985181().run(); + } + + public void run() throws Exception { + String code = "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_PARAMETER)\n" + + "@interface Simple { }\n" + + "interface Test<@Simple T> { }"; + + File srcFile = writeFile("Test.java", code); + File classesDir = new File("classes"); + classesDir.mkdirs(); + compile("-d", classesDir.getPath(), srcFile.getPath()); + String out = javap(new File(classesDir, srcFile.getName().replace(".java", ".class"))); + if (!out.contains("RuntimeInvisibleTypeAnnotations")) + throw new Exception("RuntimeInvisibleTypeAnnotations not found"); + } + + void compile(String... args) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(args, pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc != 0) + throw new Exception("Compilation failed: rc=" + rc); + } + + String javap(File classFile) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { "-v", classFile.getPath() }; + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc != 0) + throw new Exception("javap failed: rc=" + rc); + return out; + } + + File writeFile(String path, String body) throws IOException { + File f = new File(path); + FileWriter out = new FileWriter(f); + try { + out.write(body); + } finally { + out.close(); + } + return f; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/6881115/T6881115.java --- a/langtools/test/tools/javac/annotations/6881115/T6881115.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/annotations/6881115/T6881115.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,3 +1,6 @@ +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + /* * @test /nodynamiccopyright/ * @bug 6881115 6976649 @@ -6,15 +9,18 @@ * @compile/fail/ref=T6881115.out -XDrawDiagnostics T6881115.java */ +@Target({ElementType.TYPE, ElementType.TYPE_PARAMETER, ElementType.ANNOTATION_TYPE}) @interface A { B b() default @B(b2 = 1, b2 = 2); B[] b_arr() default {@B(), @B(b2 = 1, b2 = 2)}; } + @interface B { String b1(); int b2(); } + @A(b = @B(b2 = 1, b2 = 2), b_arr = {@B(), @B(b2 = 1, b2 = 2)}) -class T6881115 {} +class T6881115<@A(b = @B(b2 = 1, b2 = 2), + b_arr = {@B(), @B(b2 = 1, b2 = 2)}) X> {} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/6881115/T6881115.out --- a/langtools/test/tools/javac/annotations/6881115/T6881115.out Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/annotations/6881115/T6881115.out Wed Jan 23 13:27:24 2013 -0800 @@ -1,11 +1,16 @@ -T6881115.java:10:30: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:10:19: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:11:26: compiler.err.annotation.missing.default.value.1: B, b1,b2 -T6881115.java:11:43: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:11:32: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:17:19: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:17:8: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:18:13: compiler.err.annotation.missing.default.value.1: B, b1,b2 -T6881115.java:18:30: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:18:19: compiler.err.annotation.missing.default.value: B, b1 -10 errors +T6881115.java:14:30: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:14:19: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:15:26: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:15:43: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:15:32: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:23:19: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:23:8: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:24:13: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:24:30: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:24:19: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:25:34: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:25:23: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:26:28: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:26:45: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:26:34: compiler.err.annotation.missing.default.value: B, b1 +15 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,35 @@ +/* + * 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 + * 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 6967002 8006775 + * @summary JDK7 b99 javac compilation error (java.lang.AssertionError) + * @author Maurizio Cimadamore + * @compile/fail/ref=T6967002.out -XDrawDiagnostics T6967002.java + */ +class Test { + private static void m(byte[] octets) { + return m(octets..., ?); + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,8 @@ +T6967002.java:33:22: compiler.err.expected: ')' +T6967002.java:33:25: compiler.err.illegal.start.of.expr +T6967002.java:33:28: compiler.err.illegal.start.of.expr +T6967002.java:33:29: compiler.err.illegal.start.of.expr +T6967002.java:33:27: compiler.err.not.stmt +T6967002.java:33:30: compiler.err.expected: ';' +T6967002.java:35:2: compiler.err.premature.eof +7 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,65 @@ +import java.lang.annotation.ElementType; + +/* + * 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 6843077 8006775 + * @summary compiler crashes when visiting inner classes + * @author Mahmood Ali + * @compile InnerClass.java + */ + +import java.lang.annotation.*; + +class InnerClass { + + InnerClass() {} + InnerClass(Object o) {} + + private void a() { + new Object() { + public void method() { } + }; + } + + Object f1 = new InnerClass() { + void method() { } + }; + + Object f2 = new InnerClass() { + <@A R> void method() { } + }; + + Object f3 = new InnerClass(null) { + void method() { } + }; + + Object f4 = new InnerClass(null) { + <@A R> void method() { } + }; + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A { } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary check that type annotations may appear on void method if it is a + * method annotation too. + * @author Mahmood Ali + * @compile MultipleTargets.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class TypeUseTarget { + @A void voidMethod() { } +} + +@Target({ElementType.TYPE_USE, ElementType.METHOD}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2009 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.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.util.*; +import java.io.*; + +/* + * @test + * @summary compiler accepts all values + * @author Mahmood Ali + * @author Yuri Gaevsky + * @compile TargetTypes.java + */ + +@Target({TYPE_USE, TYPE_PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +/** wildcard bound */ +class T0x1C { + void m0x1C(List lst) {} +} + +/** wildcard bound generic/array */ +class T0x1D { + void m0x1D(List> lst) {} +} + +/** typecast */ +class T0x00 { + void m0x00(Long l1) { + Object l2 = (@A Long) l1; + } +} + +/** typecast generic/array */ +class T0x01 { + void m0x01(List list) { + List l = (List<@A T>) list; + } +} + +/** instanceof */ +class T0x02 { + boolean m0x02(String s) { + return (s instanceof @A String); + } +} + +/** object creation (new) */ +class T0x04 { + void m0x04() { + new @A ArrayList(); + } +} + +/** local variable */ +class T0x08 { + void m0x08() { + @A String s = null; + } +} + +/** method parameter generic/array */ +class T0x0D { + void m0x0D(HashMap<@A Object, List<@A List<@A Class>>> s1) {} +} + +/** method receiver */ +class T0x06 { + void m0x06(@A T0x06 this) {} +} + +/** method return type generic/array */ +class T0x0B { + Class<@A Object> m0x0B() { return null; } +} + +/** field generic/array */ +class T0x0F { + HashMap<@A Object, @A Object> c1; +} + +/** method type parameter */ +class T0x20 { + <@A T, @A U> void m0x20() {} +} + +/** class type parameter */ +class T0x22<@A T, @A U> { +} + +/** class type parameter bound */ +class T0x10 { +} + +/** method type parameter bound */ +class T0x12 { + void m0x12() {} +} + +/** class type parameter bound generic/array */ +class T0x11> { +} + + +/** method type parameter bound generic/array */ +class T0x13 { + static > T m0x13() { + return null; + } +} + +/** class extends/implements generic/array */ +class T0x15 extends ArrayList<@A T> { +} + +/** type test (instanceof) generic/array */ +class T0x03 { + void m0x03(T typeObj, Object obj) { + boolean ok = obj instanceof String @A []; + } +} + +/** object creation (new) generic/array */ +class T0x05 { + void m0x05() { + new ArrayList<@A T>(); + } +} + +/** local variable generic/array */ +class T0x09 { + void g() { + List<@A String> l = null; + } + + void a() { + String @A [] as = null; + } +} + +/** type argument in constructor call generic/array */ +class T0x19 { + T0x19() {} + + void g() { + new > T0x19(); + } +} + +/** type argument in method call generic/array */ +class T0x1B { + void m0x1B() { + Collections.emptyList(); + } +} + +/** type argument in constructor call */ +class T0x18 { + T0x18() {} + + void m() { + new <@A Integer> T0x18(); + } +} + +/** type argument in method call */ +class T0x1A { + public static T m() { return null; } + static void m0x1A() { + T0x1A.<@A Integer, @A Short>m(); + } +} + +/** class extends/implements */ +class T0x14 extends @A Object implements @A Serializable, @A Cloneable { +} + +/** exception type in throws */ +class T0x16 { + void m0x16() throws @A Exception {} +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary check that type annotations may appear on all type parameter + * @author Mahmood Ali + * @compile TypeParameterTarget.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class TypeUseTarget<@A K extends Object> { + String[] field; + + <@A K, @A V> String genericMethod(K k) { return null; } +} + +interface MyInterface { } + +@interface MyAnnotation { } + +@Target(ElementType.TYPE_PARAMETER) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009 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.io.*; +import java.util.Set; +import java.util.HashSet; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.ElementFilter; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.JavaCompiler.CompileState; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Context; + +/* + * @test + * @summary test that type processors are run when -proc:only is passed. + * This class implements the functionality of a type processor, as previously + * embodied by the AbstractTypeProcessor class. + * + * @author Mahmood Ali + * @author Werner Dietl + */ +@SupportedAnnotationTypes("*") +public class TypeProcOnly extends AbstractProcessor { + private static final String INDICATOR = "INDICATOR"; + + private final AttributionTaskListener listener = new AttributionTaskListener(); + private final Set elements = new HashSet(); + + @Override + public final void init(ProcessingEnvironment env) { + super.init(env); + JavacTask.instance(env).addTaskListener(listener); + Context ctx = ((JavacProcessingEnvironment)processingEnv).getContext(); + JavaCompiler compiler = JavaCompiler.instance(ctx); + compiler.shouldStopPolicyIfNoError = CompileState.max( + compiler.shouldStopPolicyIfNoError, + CompileState.FLOW); + } + + @Override + public final boolean process(Set annotations, + RoundEnvironment roundEnv) { + for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) { + elements.add(elem.getQualifiedName()); + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private final class AttributionTaskListener implements TaskListener { + @Override + public void started(TaskEvent e) { } + + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.ANALYZE) + return; + + if (!elements.remove(e.getTypeElement().getQualifiedName())) + return; + + System.out.println(INDICATOR); + } + } + + + private static File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("class Test { }"); + out.close(); + return f; + } + + public static void main(String[] args) throws Exception { + PrintStream prevOut = System.out; + + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(bytes); + System.setOut(out); + + try { + File f = writeTestFile(); + com.sun.tools.javac.Main.compile(new String[] {"-proc:only", "-processor", "TypeProcOnly", f.getAbsolutePath()}); + } finally { + System.setOut(prevOut); + } + + if (bytes.toString().trim().equals(INDICATOR)) { + System.out.println("PASSED"); + } else { + throw new Exception("Processor did not run correctly. Output: " + bytes); + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary check that type annotations may appear on all type declarations + * @author Mahmood Ali + * @compile TypeUseTarget.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@A +class TypeUseTarget { + @A String @A [] field; + + @A String test(@A TypeUseTarget this, @A String param, @A String @A ... vararg) { + @A Object o = new @A String @A [3]; + TypeUseTarget<@A String> target; + return (@A String) null; + } + + @A String genericMethod(K k) { return null; } + @Decl @A String genericMethod1(K k) { return null; } + @A @Decl String genericMethod2(K k) { return null; } + @Decl @A String genericMethod3(K k) { return null; } + @Decl String genericMethod4(K k) { return null; } + @A @Decl String genericMethod5(K k) { return null; } +} + +@A +interface MyInterface { } + +@A +@interface MyAnnotation { } + +@Target(ElementType.TYPE_USE) +@interface A { } + +@interface Decl { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2010 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 Checks the annotation types targeting array types + */ + +import com.sun.tools.javac.api.JavacTool; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.lang.annotation.*; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class AnnotatedArrayOrder { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (!expectedLocations.isEmpty()) { + throw new AssertionError("Didn't found all annotations: " + expectedLocations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + String annotation = annos.get(0).toString(); + + if (!expectedLocations.containsKey(annotation)) + throw new AssertionError("Found unexpected annotation: " + annotation + expectedLocations); + + int expected = expectedLocations.get(annotation); + if (found != expected) + throw new AssertionError("The expected array length for this error doesn't match"); + + expectedLocations.remove(annotation); + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + private int arrayLength(Tree tree) { + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + // expectedLocations values: + static Map expectedLocations = new HashMap(); + + // visited code + @A String @C [] @B [] field; + static { + // Shouldn't find @A(), as it is field annotation + expectedLocations.put("@B()", 1); + expectedLocations.put("@C()", 2); + } + + List<@D String @F [] @E []> typearg; + static { + expectedLocations.put("@D()", 0); + expectedLocations.put("@E()", 1); + expectedLocations.put("@F()", 2); + } + + void varargSimple(@G String @H ... vararg1) { } + static { + // Shouldn't find @G(), as it is a parameter annotation + expectedLocations.put("@H()", 1); + } + + void varargLong(@I String @L [] @K [] @J ... vararg2) { } + static { + // Shouldn't find @I(), as it is a parameter annotation + expectedLocations.put("@J()", 1); + expectedLocations.put("@K()", 2); + expectedLocations.put("@L()", 3); + } + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface D {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface E {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface F {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface G {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface H {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface I {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface J {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface K {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface L {} +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2010 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 Checks that the interaction between annotated and unannotated + * array levels in array creation trees + */ + +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.tree.JCTree.JCNewArray; +import java.lang.annotation.*; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class ArrayCreationTree { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayCreationTree.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + int foundAnnotations = 0; + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (foundAnnotations != expectedAnnotations) { + throw new AssertionError("Expected " + expectedAnnotations + + " annotations but found: " + foundAnnotations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + if (annos.isEmpty()) return; + + String annotation = annos.get(0).toString(); + foundAnnotations++; + + int expected = -1; + if (annotation.equals("@A()")) + expected = 0; + else if (annotation.equals("@B()")) + expected = 1; + else if (annotation.equals("@C()")) + expected = 2; + else + throw new AssertionError("found an unexpected annotation: " + annotation); + if (found != expected) { + throw new AssertionError("Unexpected found length" + + ", found " + found + " but expected " + expected); + } + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + public Void visitNewArray(NewArrayTree node, Void ignore) { + // the Tree API hasn't been updated to expose annotations yet + JCNewArray newArray = (JCNewArray)node; + int totalLength = node.getDimensions().size() + + arrayLength(node.getType()) + + ((newArray.getInitializers() != null) ? 1 : 0); + testAnnotations(newArray.annotations, totalLength); + int count = 0; + for (List annos : newArray.dimAnnotations) { + testAnnotations(annos, totalLength - count); + count++; + } + return super.visitNewArray(node, ignore); + } + + private int arrayLength(Tree tree) { + // TODO: the tree is null when called with node.getType(). Why? + if (tree==null) return -1; + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + static int expectedAnnotations = 21; + + Object a1 = new @A Object @C [2] @B [1]; + Object b1 = new @A Object @C [2] @B [ ]; + Object c1 = new @A Object @C [ ] @B [ ] { }; + + Object a2 = new @A Object @C [2] [1]; + Object b2 = new @A Object @C [2] [ ]; + Object c2 = new @A Object @C [ ] [ ] { }; + + Object a3 = new @A Object [2] @B [1]; + Object b3 = new @A Object [2] @B [ ]; + Object c3 = new @A Object [ ] @B [ ] { }; + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2010 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 Checks that the interaction between annotated and unannotated + * array levels + */ + +import com.sun.tools.javac.api.JavacTool; +import java.lang.annotation.*; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class ArrayPositionConsistency { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayPositionConsistency.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + int foundAnnotations = 0; + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (foundAnnotations != expectedAnnotations) { + throw new AssertionError("Expected " + expectedAnnotations + + " annotations but found: " + foundAnnotations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + String annotation = annos.get(0).toString(); + foundAnnotations++; + + int expected = -1; + if (annotation.equals("@A()")) + expected = 0; + else if (annotation.equals("@B()")) + expected = 1; + else if (annotation.equals("@C()")) + expected = 2; + else + throw new AssertionError("found an unexpected annotation: " + annotation); + if (found != expected) { + throw new AssertionError("Unexpected found length" + + ", found " + found + " but expected " + expected); + } + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + private int arrayLength(Tree tree) { + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + static int expectedAnnotations = 23; + + // visited code + @A String @C [] @B [] field1; + @A String @C [] [] field2; + @A String [] @B [] field3; + String [] @B [] field4; + + @A List @C [] @B [] genfield1; + @A List @C [] [] genfield2; + @A List [] @B [] genfield3; + List [] @B [] genfield4; + + List<@A String @C [] @B []> typearg1; + List<@A String @C [] []> typearg2; + List<@A String [] @B []> typearg3; + List< String [] @B []> typearg4; + + void vararg1(@A String @C [] @B ... arg) {} + void vararg2(@A String @C [] ... arg) {} + void vararg3(@A String [] @B ... arg) {} + void vararg4( String [] @B ... arg) {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary test scopes of attribution + * @author Mahmood Ali + * @compile Scopes.java + */ +class Scopes { + + void test(@A(VALUE) Scopes this) { } + void test1(@A(value=VALUE) Scopes this) { } + + private static final int VALUE = 1; + @interface A { int value(); } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,195 @@ +/* + * 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +public class ClassfileTestHelper { + int expected_tinvisibles = 0; + int expected_tvisibles = 0; + int expected_invisibles = 0; + int expected_visibles = 0; + + //Makes debugging much easier. Set to 'false' for less output. + public Boolean verbose = true; + void println(String msg) { if(verbose) System.out.println(msg); } + + File writeTestFile(String fname, String source) throws IOException { + File f = new File(fname); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(source); + out.close(); + return f; + } + + File compile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { + "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + ClassFile getClassFile(URL url) throws IOException, ConstantPoolException { + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + /************ Helper annotations counting methods ******************/ + void test(ClassFile cf) { + test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true); + test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false); + //RuntimeAnnotations since one annotation can result in two attributes. + test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true); + 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) { + 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 the result of Attributes.getIndex according to expectations + // encoded in the class/field/method name; increment annotations counts. + void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) { + String testtype = ttype; + String name = null; + int index = -1; + Attribute attr = 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); + 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); + break; + default: + name = cf.getName(); + index = cf.attributes.getIndex(cf.constant_pool, annName); + if(index!= -1) attr = cf.attributes.get(index); + } + } catch(ConstantPoolException cpe) { cpe.printStackTrace(); } + + if (index != -1) { + assert attr instanceof RuntimeTypeAnnotations_attribute; + if(isTAattr) { //count RuntimeTypeAnnotations + RuntimeTypeAnnotations_attribute tAttr = + (RuntimeTypeAnnotations_attribute)attr; + println(testtype + ": " + name + ", " + annName + ": " + + tAttr.annotations.length ); + allt += tAttr.annotations.length; + if (visible) + tvisibles += tAttr.annotations.length; + else + tinvisibles += tAttr.annotations.length; + } else { + RuntimeAnnotations_attribute tAttr = + (RuntimeAnnotations_attribute)attr; + println(testtype + ": " + name + ", " + annName + ": " + + tAttr.annotations.length ); + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + } + + void countAnnotations() { + errors=0; + int expected_allt = expected_tvisibles + expected_tinvisibles; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_allt != allt) { + errors++; + System.err.println("Failure: expected " + expected_allt + + " type annotations but found " + allt); + } + if (expected_all != all) { + errors++; + System.err.println("Failure: expected " + expected_all + + " annotations but found " + all); + } + if (expected_tvisibles != tvisibles) { + errors++; + System.err.println("Failure: expected " + expected_tvisibles + + " typevisible annotations but found " + tvisibles); + } + + if (expected_tinvisibles != tinvisibles) { + errors++; + System.err.println("Failure: expected " + expected_tinvisibles + + " typeinvisible annotations but found " + tinvisibles); + } + allt=0; + tvisibles=0; + tinvisibles=0; + all=0; + visibles=0; + invisibles=0; + } + + int errors; + int allt; + int tvisibles; + int tinvisibles; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,369 @@ +/* + * 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 8005877 8004829 8005681 8006734 8006775 + * @ignore + * @summary Combinations of Target ElementTypes on (repeated)type annotations. + */ + +import com.sun.tools.classfile.*; +import java.io.File; + +public class CombinationsTargetTest1 extends ClassfileTestHelper { + // Helps identify test case in event of failure. + int testcount = 0; + int src1 = 1, src2 = 2, src4 = 4, + src5 = 5, src6 = 6, src7 = 7; + + String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR", + "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"}; + + // local class tests will have an inner class. + Boolean hasInnerClass=false; + String innerClassname=""; + + public static void main(String[] args) throws Exception { + new CombinationsTargetTest1().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 + }; + for(Boolean[] bCombo : bRepeat) { + As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2]; + 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); + 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); + 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); + } + } + } + } + + 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 { + ++testcount; + expected_tvisibles = tvis; + expected_tinvisibles = tinv; + expected_visibles = vis; + expected_invisibles = inv; + File testFile = null; + String tname="Test" + N.toString(); + hasInnerClass=false; + 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; + + 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); + } catch (Error err) { + System.err.println("Failed compile. Source:\n" + sourceString); + throw err; + } + //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 cf = ClassFile.read(classFile); + + //Test class,fields and method counts. + test(cf); + + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + countAnnotations(); + if (errors > 0) { + System.err.println( testDef ); + System.err.println( "Source:\n" + sourceString ); + throw new Exception( errors + " errors found" ); + } + println("Pass"); + } + + // + // Source for test cases + // + String sourceString(String testname, String retentn, String annot2, + Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, + int 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.HashMap; \n" + + "import java.util.Map; \n\n"); + + String sourceBase = new String("@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( AC.class )\n" + + "@interface A { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(A.class)\n" + + "@interface AC { A[] value(); }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( BC.class )\n" + + "@interface B { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(B.class)\n" + + "@interface BC { B[] value(); } \n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_PARAMETER,_OTHER_})\n" + + "@interface C { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainedBy(DC.class)\n" + + "@interface D { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainerFor(D.class) \n" + + "@interface DC { D[] value(); }\n\n"); + + // Test case sources with sample generated source. + switch(src) { + case 1: // repeating type annotations at class level + /* + * @A @B class Test1 { + * @A @B Test1(){} + * @A @B Integer i1 = 0; + * String @A @B [] @A @B [] sa = null; + * // type usage in method body + * String test(Test1 this, String param, String ... vararg) { + * Object o = new String [3]; + * return (String) null; + * }} + */ + 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"; + break; + case 2: // (repeating) type annotations on method. + /* + * class Test12 { + * Test12(){} + * // type usage on method + * @A @B String test(@A @B Test12 this, @A @B String param, @A @B String @A @B ... vararg) { + * Object o = new String [3]; + * return (String) null; + * }} + */ + 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"; + break; + case 4: //(repeating) annotations on wildcard, type arguments in anonymous class. + /* + * class Test13 { + * public T data = null; + * T getData() { return data;} + * String mtest( Test13 t){ return t.getData(); } + * public void test() { + * mtest( new Test13<@A @B String>() { + * void m1(List<@A @B ? extends @A @B Object> lst) {} + * void m2() throws@A @B Exception { } + * }); + * } + * } + */ + source = new String( source + + "// (repeating) annotations on wildcard, type arguments in anonymous class. \n" + + "class " + testname + " {\n" + + " public T data = null;\n" + + " T getData() { return data;}\n" + + " String mtest( " + testname + " 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"; + break; + case 5: // (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> { + * Map, Integer> map = + * new HashMap, Integer>(); + * Map,Integer> map2 = new HashMap<>(); + * String test(Test2 this) { return null;} + * String genericMethod(T t) { return null; } + * } + */ + 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, Integer> map =\n" + + " new HashMap, Integer>();\n" + + " Map,Integer> map2 = new HashMap<>();\n" + + " String test(" + testname + " this) { return null;}\n" + + " 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. + /* + * class Test14 { + * Map, Integer> map = + * new HashMap, Integer>(); + * Map, Integer> map2 = new HashMap<>(); + * String test(@A @B Test14<@D T> this) { return null;} + * <@C @D T> @A @B String genericMethod(@A @B @D T t) { return null; } + * } + */ + source = new String( source + + "// (repeating) annotations on type parameters, bounds and type arguments on method. \n" + + "class " + testname + " {\n" + + " Map, Integer> map =\n" + + " new HashMap, Integer>();\n" + + " Map, 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. + /* + * class Test7{ + * Map, E > foo(E e) { + * class maptest <@A @B @D E> { + * Map,@A @B @D E> getMap() { + * return new HashMap,E>(); + * } + * } + * return new maptest().getMap(); + * } + * Map,String> shm = foo(new String("hello")); + * } + */ + source = new String( source + + "// (repeating)annotations on type parameters of class, method return value in method. \n" + + "class "+ testname + "{\n" + + " Map, E > foo(E e) {\n" + + " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest + " Map,_As_ _Bs_ _Ds_ E> getMap() { \n" + + " return new HashMap,E>();\n" + + " }\n" + + " }\n" + + " return new maptest().getMap();\n" + + " }\n" + + " Map,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; + } + return imports + source; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,285 @@ +/* + * 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 8005877 8004829 8005681 8006734 8006775 + * @ignore + * @summary Combinations of Target ElementTypes on (repeated)type annotations. + */ + +import com.sun.tools.classfile.*; +import java.io.File; + +public class CombinationsTargetTest2 extends ClassfileTestHelper { + // Helps identify test case in event of failure. + int testcount = 0; + int src3 = 3, src8 = 8, src9 = 9; + + String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR", + "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"}; + + // local class tests will have an inner class. + Boolean hasInnerClass=false; + String innerClassname=""; + + public static void main(String[] args) throws Exception { + new CombinationsTargetTest2().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 + }; + 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); + 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); + break; + default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/ + break; + } + } + } + } + + 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 { + ++testcount; + expected_tvisibles = tvis; + expected_tinvisibles = tinv; + expected_visibles = vis; + expected_invisibles = inv; + File testFile = null; + String tname="Test" + N.toString(); + hasInnerClass=false; + 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; + +// 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; +// } + + 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); + } catch (Error err) { + System.err.println("Failed compile. Source:\n" + sourceString); + throw err; + } + //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 cf = ClassFile.read(classFile); + + //Test class,fields and method counts. + test(cf); + + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + countAnnotations(); + if (errors > 0) { + System.err.println( testDef ); + System.err.println( "Source:\n" + sourceString ); + throw new Exception( errors + " errors found" ); + } + println("Pass"); + } + + // + // Source for test cases + // + String sourceString(String testname, String retentn, String annot2, + Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, + int 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.HashMap; \n" + + "import java.util.Map; \n\n"); + + String sourceBase = new String("@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( AC.class )\n" + + "@interface A { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(A.class)\n" + + "@interface AC { A[] value(); }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( BC.class )\n" + + "@interface B { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(B.class)\n" + + "@interface BC { B[] value(); } \n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainedBy(DC.class)\n" + + "@interface D { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainerFor(D.class) \n" + + "@interface DC { D[] value(); }\n\n"); + + // Test case sources with sample generated source + switch(src) { + case 3: // (repeating) type annotations on field in method body + /* + * class Test1 { + * Test1(){} + * // type usage in method body + * String test(Test1 this, String param, String ... vararg) { + * @A @B + * Object o = new @A @B String @A @B [3]; + * return (@A @B String) null; + * }} + */ + 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. + /* + * class Test2 { + * Map, Integer> map = + * new HashMap<@A @B List<@A @B String>, @A @B Integer>(); + * Map, Integer> map2 = new @A @B HashMap<>(); + * String test(Test2 this) { return null;} + * String genericMethod(T t) { return null; } + * } + */ + source = new String( source + + "// (repeating) annotations on type parameters, bounds and type arguments. \n" + + "class " + testname + " {\n" + + " Map, Integer> map =\n" + + " new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" + + " Map, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" + + " String test(" + testname + " this) { return null;}\n" + + " 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. + /* + * class Test3{ + * Map, E > foo(E e) { + * class maptest { + * Map,E> getMap() { + * Map,E> Em = new HashMap,@A @B @D E>(); + * return Em; + * } + * } + * return new maptest().getMap(); + * } + * Map,String> shm = foo(new String("hello")); + * } + */ + source = new String( source + + "// (repeating)annotations on type parameters of class, method return value in method. \n" + + "class "+ testname + "{\n" + + " Map, E > foo(E e) {\n" + + " class maptest {\n" + // inner class $1maptest + " Map,E> getMap() { \n" + + " Map,E> Em = new HashMap,_As_ _Bs_ _Ds_ E>();\n" + + " return Em;\n" + + " }\n" + + " }\n" + + " return new maptest().getMap();\n" + + " }\n" + + " Map,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; + + } + return imports + source; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,82 @@ +/* + * 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6917130 8006775 + * @summary test that optimized away annotations are not emited to classfile + */ + +public class DeadCode extends ClassfileTestHelper { + public static void main(String[] args) throws Exception { + new DeadCode().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 1; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("DeadCode$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + void test() { + List o = null; + o.toString(); + + @A String m; + if (false) { + @A String a; + @A String b = "m"; + b.toString(); + List c = null; + c.toString(); + } + } + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 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.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test ClassLiterals + * @summary test that new type arguments are emitted to classfile + */ + +public class NewTypeArguments extends ClassfileTestHelper{ + public static void main(String[] args) throws Exception { + new NewTypeArguments().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 3; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("NewTypeArguments$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + Test(E e) {} + + void test() { + new <@A String> Test(null); + new <@A List<@A String>> Test(null); + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2008 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.io.*; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test NoTargetAnnotations + * @summary test that annotations with no Target meta type is emitted + * only once as declaration annotation + */ +public class NoTargetAnnotations { + + public static void main(String[] args) throws Exception { + new NoTargetAnnotations().run(); + } + + public void run() throws Exception { + ClassFile cf = getClassFile("NoTargetAnnotations$Test.class"); + for (Field f : cf.fields) { + test(cf, f); + testDeclaration(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + testDeclaration(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + /************ Helper annotations counting methods ******************/ + 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); + } + + void testDeclaration(ClassFile cf, Method m) { + testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true); + testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false); + } + + void testDeclaration(ClassFile cf, Field m) { + testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true); + testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false); + } + + // 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; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void testDecl(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 RuntimeAnnotations_attribute; + RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr; + this.declAnnotations += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void testDecl(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 RuntimeAnnotations_attribute; + RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr; + this.declAnnotations += tAttr.annotations.length; + } + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-XDTA:writer", "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + if (expected_decl != declAnnotations) { + errors++; + System.err.println("expected " + expected_decl + + " declaration annotations but found " + declAnnotations); + } + } + + int errors; + int all; + int visibles; + int invisibles; + + int declAnnotations; + + /*********************** Test class *************************/ + static int expected_invisibles = 0; + static int expected_visibles = 0; + static int expected_decl = 1; + + static class Test { + @Retention(RetentionPolicy.RUNTIME) + @interface A {} + + @A String method() { + return null; + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 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.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary test that typecasts annotation are emitted if only the cast + * expression is optimized away + */ + +public class TypeCasts extends ClassfileTestHelper{ + public static void main(String[] args) throws Exception { + new TypeCasts().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 4; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("TypeCasts$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + void emit() { + Object o = null; + String s = null; + + String a0 = (@A String)o; + Object a1 = (@A Object)o; + + String b0 = (@A String)s; + Object b1 = (@A Object)s; + } + + void alldeadcode() { + Object o = null; + + if (false) { + String a0 = (@A String)o; + } + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009 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.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test Wildcards + * @bug 6843077 8006775 + * @summary test that annotations target wildcards get emitted to classfile + */ +public class Wildcards extends ClassfileTestHelper { + public static void main(String[] args) throws Exception { + new Wildcards().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 3; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("Wildcards$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + List f; + + List test(List p) { + List l; // not counted... gets optimized away + return null; + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Import clauses cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedImport.out -XDrawDiagnostics AnnotatedImport.java + */ + +import java.@A util.List; +import @A java.util.Map; +import java.util.@A HashMap; + +class AnnotatedImport { } + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,7 @@ +AnnotatedImport.java:9:13: compiler.err.expected: token.identifier +AnnotatedImport.java:9:14: compiler.err.expected3: class, interface, enum +AnnotatedImport.java:10:7: compiler.err.expected: token.identifier +AnnotatedImport.java:10:10: compiler.err.expected: ';' +AnnotatedImport.java:11:18: compiler.err.expected: token.identifier +AnnotatedImport.java:11:19: compiler.err.expected3: class, interface, enum +6 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Package declarations cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedPackage1.out -XDrawDiagnostics AnnotatedPackage1.java + */ + +package name.@A p1.p2; + +class AnnotatedPackage1 { } + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +AnnotatedPackage1.java:9:14: compiler.err.expected: token.identifier +AnnotatedPackage1.java:9:15: compiler.err.expected3: class, interface, enum +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Package declarations cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedPackage2.out -XDrawDiagnostics AnnotatedPackage2.java + */ + +package @A p1.p2; + +class AnnotatedPackage2 { } + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +AnnotatedPackage2.java:9:8: compiler.err.expected: token.identifier +AnnotatedPackage2.java:9:10: compiler.err.expected3: class, interface, enum +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test that only Java 8 allows type annotations + * @author Mahmood Ali + * @compile/fail/ref=AnnotationVersion.out -XDrawDiagnostics -Xlint:-options -source 1.6 AnnotationVersion.java + * @compile/fail/ref=AnnotationVersion7.out -XDrawDiagnostics -Xlint:-options -source 1.7 AnnotationVersion.java + */ +class AnnotationVersion { + public void method(@A AnnotationVersion this) { } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.6 +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.7 +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary A cast cannot consist of only an annotation. + * @author Werner Dietl + * @compile/fail/ref=BadCast.out -XDrawDiagnostics BadCast.java + */ +class BadCast { + static void main() { + Object o = (@A) ""; + } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +BadCast.java:10:19: compiler.err.illegal.start.of.type +1 error \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,41 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006733 8006775 + * @ignore + * @summary A static outer class cannot be annotated. + * @author Werner Dietl + * @compile/fail/ref=CantAnnotateStaticClass.out -XDrawDiagnostics CantAnnotateStaticClass.java + */ + +import java.util.List; +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + static class Outer { + class Inner {} + } + + // 8 errors: + @A Outer.Inner f1; + @A Outer.Inner f1r() { return null; } + void f1p(@A Outer.Inner p) { } + void f1c(Object o) { + Object l = (@A Outer.Inner) o; + } + + List<@A Outer.Inner> f2; + List<@A Outer.Inner> f2r() { return null; } + void f2p(List<@A Outer.Inner> p) { } + void f2c(Object o) { + Object l = (List<@A Outer.Inner>) o; + } + + // OK: + @A Outer g1; + List<@A Outer> g2; + Outer. @A Inner g3; + List g4; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,1 @@ +dummy \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete array declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics IncompleteArray.java + */ +class IncompleteArray { + int @A [] @A var; +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +IncompleteArray.java:9:13: compiler.err.illegal.start.of.type +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete vararg declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteVararg.out -XDrawDiagnostics IncompleteVararg.java + */ +class IncompleteArray { + // the last variable may be vararg + void method(int @A test) { } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +IncompleteVararg.java:10:19: compiler.err.illegal.start.of.type +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test indexing of an array + * @author Mahmood Ali + * @compile/fail/ref=IndexArray.out -XDrawDiagnostics IndexArray.java + */ +class IndexArray { + int[] var; + int a = var @A [1]; +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +IndexArray.java:10:15: compiler.err.illegal.start.of.expr +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,69 @@ +import java.lang.annotation.*; +import java.util.List; + +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test that compiler doesn't warn about annotated redundant casts + * @author Mahmood Ali + * @author Werner Dietl + * @compile/ref=LintCast.out -Xlint:cast -XDrawDiagnostics LintCast.java + */ +class LintCast { + void unparameterized() { + String s = "m"; + String s1 = (String)s; + String s2 = (@A String)s; + } + + void parameterized() { + List l = null; + List l1 = (List)l; + List l2 = (List<@A String>)l; + } + + void array() { + int @A [] a = null; + int[] a1 = (int[])a; + int[] a2 = (int @A [])a; + } + + void sameAnnotations() { + @A String annotated = null; + String unannotated = null; + + // compiler ignore annotated casts even if redundant + @A String anno1 = (@A String)annotated; + + // warn if redundant without an annotation + String anno2 = (String)annotated; + String unanno2 = (String)unannotated; + } + + void more() { + Object @A [] a = null; + Object[] a1 = (Object[])a; + Object[] a2 = (Object @A [])a; + + @A List l3 = null; + List l4 = (List)l3; + List l5 = (@A List)l3; + + List<@A String> l6 = null; + List l7 = (List)l6; + List l8 = (List<@A String>)l6; + + @A Object o = null; + Object o1 = (Object)o; + Object o2 = (@A Object)o; + + Outer. @A Inner oi = null; + Outer.Inner oi1 = (Outer.Inner)oi; + Outer.Inner oi2 = (Outer. @A Inner)oi; + } + + class Outer { class Inner {} } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,11 @@ +LintCast.java:15:21: compiler.warn.redundant.cast: java.lang.String +LintCast.java:21:27: compiler.warn.redundant.cast: java.util.List +LintCast.java:27:20: compiler.warn.redundant.cast: (@A :: int[]) +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:49:27: compiler.warn.redundant.cast: java.util.List +LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List +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 diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary test old array syntax + * @author Mahmood Ali + * @compile/fail -XDrawDiagnostics OldArray.java + */ +class OldArray { + String [@A] s() { return null; } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check that A is accessible in the class type parameters + * @author Mahmood Ali + * @compile/fail/ref=Scopes.out -XDrawDiagnostics Scopes.java + */ +class Scopes { + // UniqueInner is not visible in the type parameters. + // One has to use Scopes.UniqueInner. + // Annotations with the default @Target are not allowed there, + // so we also get the second error about the invalid location. + // Adding the target here doesn't matter, as we don't resolve + // the annotation type. + // @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface UniqueInner { }; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +Scopes.java:8:25: compiler.err.cant.resolve: kindname.class, UniqueInner, , +Scopes.java:8:24: compiler.err.annotation.type.not.applicable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary static field access isn't a valid location + * @author Mahmood Ali + * @compile/fail/ref=StaticFields.out -XDrawDiagnostics StaticFields.java + */ +class C { + int f; + int a = @A C.f; +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +StaticFields.java:10:17: compiler.err.illegal.start.of.expr +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary static methods don't have receivers + * @author Mahmood Ali + * @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java + */ +class StaticMethods { + static void main(@A StaticMethods this) { } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,40 @@ +/* + * 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 8006703 8006775 + * @summary Ensure that TYPE_USE and FIELD work together. + * @author Werner Dietl + * @compile TypeAndField.java + */ +import java.lang.annotation.*; + +class TypeAndField { + @TA Integer i; + @TA int j; +} + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE_USE, ElementType.FIELD}) +@interface TA { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary test type annotation on void generic methods + * @author Mahmood Ali + * @compile/fail VoidGenericMethod.java + */ +class VoidGenericMethod { + public @A void method() { } +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + String @A(value = 2, value = 1) [] s; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:26: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + String @A @A [] s; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:12: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:15: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + String @A [] s; + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:11:12: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + String @A [] s; + } +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:12: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void method() { + class Inner<@A(value = 2, value = 1) K> {} + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:31: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + void innermethod() { + class Inner<@A @A K> { } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:17: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:20: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ +class InvalidLocation { + void innermethod() { + class Inner<@A K> {} + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:10:17: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void innermethod() { + class Inner<@A K> { } + } +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:17: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + String[] a = new String @A(value = 2, value = 1) [5] ; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:43: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + String[] a = new String @A @A [5] ; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:29: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:32: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + String[] s = new String @A [5] ; + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:11:29: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + String[] a = new String @A [5]; + } +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:29: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,99 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Ensure unresolved upper bound annotation is handled correctly + * @author Werner Dietl + * @compile/fail/ref=BrokenAnnotation.out -XDrawDiagnostics BrokenAnnotation.java + */ + +// No import, making the annotation @A invalid. +// import java.lang.annotation.*; + +// Works: @Broke.A class... +// Works: class Broke<@Broke.A T> { +// Used to fail: +class BrokenAnnotation { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A { } +} + +// If the Annotation is e.g. on the top-level class, we +// get something like this: +// +// Broke.java:6: cannot find symbol +// symbol : class Target +// location: class Broke +// @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +// ^ +// 1 error +// +// When the annotation is in the upper bound, one used to get +// the following stack trace: +// +// An exception has occurred in the compiler (1.7.0-jsr308-1.2.7). Please report this bug so we can fix it. For instructions, see http://types.cs.washington.edu/checker-framework/current/README-jsr308.html#reporting-bugs . Thank you. +// java.lang.NullPointerException +// at com.sun.tools.javac.code.Type.isCompound(Type.java:346) +// at com.sun.tools.javac.code.Types.getBounds(Types.java:1940) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitTypeVar(RichDiagnosticFormatter.java:534) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitTypeVar(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1049) +// at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3809) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visit(RichDiagnosticFormatter.java:450) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitClassType(RichDiagnosticFormatter.java:518) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitClassType(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:596) +// at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3809) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessType(RichDiagnosticFormatter.java:442) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessArgument(RichDiagnosticFormatter.java:172) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessDiagnostic(RichDiagnosticFormatter.java:155) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessArgument(RichDiagnosticFormatter.java:178) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessDiagnostic(RichDiagnosticFormatter.java:155) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.format(RichDiagnosticFormatter.java:111) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.format(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.util.Log.writeDiagnostic(Log.java:514) +// at com.sun.tools.javac.util.Log.report(Log.java:496) +// at com.sun.tools.javac.comp.Resolve.logResolveError(Resolve.java:2160) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1553) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1580) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1592) +// at com.sun.tools.javac.comp.Resolve.resolveIdent(Resolve.java:1653) +// at com.sun.tools.javac.comp.Attr.visitIdent(Attr.java:2191) +// at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:1873) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribAnnotationTypes(Attr.java:605) +// at com.sun.tools.javac.comp.MemberEnter.complete(MemberEnter.java:944) +// at com.sun.tools.javac.code.Symbol.complete(Symbol.java:432) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:832) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.flags(Symbol.java:775) +// at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:350) +// at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:346) +// at com.sun.tools.javac.comp.Resolve.findMemberType(Resolve.java:1346) +// at com.sun.tools.javac.comp.Resolve.findIdentInType(Resolve.java:1512) +// at com.sun.tools.javac.comp.Attr.selectSym(Attr.java:2434) +// at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:2312) +// at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1805) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribAnnotationTypes(Attr.java:605) +// at com.sun.tools.javac.comp.Attr.visitAnnotatedType(Attr.java:3016) +// at com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2253) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribTypeVariables(Attr.java:569) +// at com.sun.tools.javac.comp.MemberEnter.complete(MemberEnter.java:955) +// at com.sun.tools.javac.code.Symbol.complete(Symbol.java:432) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:832) +// at com.sun.tools.javac.comp.Enter.complete(Enter.java:500) +// at com.sun.tools.javac.comp.Enter.main(Enter.java:478) +// at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:950) +// at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:841) +// at com.sun.tools.javac.main.Main.compile(Main.java:441) +// at com.sun.tools.javac.main.Main.compile(Main.java:358) +// at com.sun.tools.javac.main.Main.compile(Main.java:347) +// at com.sun.tools.javac.main.Main.compile(Main.java:338) +// at com.sun.tools.javac.Main.compile(Main.java:76) +// at com.sun.tools.javac.Main.main(Main.java:61) diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +BrokenAnnotation.java:16:6: compiler.err.cant.resolve.location: kindname.class, Target, , , (compiler.misc.location: kindname.class, BrokenAnnotation, null) +BrokenAnnotation.java:15:34: compiler.err.annotation.type.not.applicable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:9:56: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:9:35: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:9:38: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:9:33: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +import java.lang.annotation.*; + +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { +} + +@Target(ElementType.TYPE_USE) +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:40: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values in receiver + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test(@A(value = 2, value = 1) DuplicateAnnotationValue this) { } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:27: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations in receiver + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test(@A @A DuplicateTypeAnnotation this) { } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:13: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:16: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test(@A InvalidLocation this) { + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:10:13: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test(@A MissingAnnotationValue this) { } +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:13: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008, 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 8006775 + * @summary Ensure that nested classes/methods work + * @author Werner Dietl + * @compile Nesting.java + */ +@interface A { } + +class Nesting { + void top(@A Nesting this) {} + + class B { + void inB(@A B this) {} + } + + void meth(@A Nesting this) { + class C { + void inMethod(@A C this) {} + } + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008, 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 8006775 + * @summary the receiver parameter and static methods/classes + * @author Werner Dietl + * @compile/fail/ref=StaticThings.out -XDrawDiagnostics StaticThings.java + */ +class Test { + // bad + static void test1(Test this) {} + + // bad + static Object test2(Test this) { return null; } + + class Nested1 { + // good + void test3a(Nested1 this) {} + // good + void test3b(Test.Nested1 this) {} + // No static methods + // static void test3c(Nested1 this) {} + } + static class Nested2 { + // good + void test4a(Nested2 this) {} + // good + void test4b(Test.Nested2 this) {} + // bad + static void test4c(Nested2 this) {} + // bad + static void test4d(Test.Nested2 this) {} + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +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 diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008, 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 8006775 + * @summary the receiver parameter has the type of the surrounding class + * @author Werner Dietl + * @compile/fail/ref=WrongType.out -XDrawDiagnostics WrongType.java + */ + +@interface A {} + +class WrongType { + Object f; + + void good1(@A WrongType this) {} + + void good2(@A WrongType this) { + this.f = null; + Object o = this.f; + } + + void bad1(@A Object this) {} + + void bad2(@A Object this) { + this.f = null; + Object o = this.f; + } + + void wow(@A XYZ this) { + this.f = null; + } + + class Inner { + void good1(@A Inner this) {} + void good2(@A WrongType.Inner this) {} + + void outerOnly(@A WrongType this) {} + void wrongInner(@A Object this) {} + void badOuter(@A Outer.Inner this) {} + void badInner(@A WrongType.XY this) {} + } + + class Generics { + void m(Generics this) {} + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +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 diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for Duplicate annotation value + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + new @A String(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:9: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + new @A @A String(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:9: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:12: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + new @A String(); + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:11:9: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + new @A String(); + } +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + DuplicateAnnotationValue<@A(value = 2, value = 1) String> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + DuplicateTypeAnno<@A @A String> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:21: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:24: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + InvalidLocation<@A String> l; +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + MissingAnnotationValue<@A String> l; +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue<@A(value = 2, value = 1) K> { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:9:46: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno<@A @A K> { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:9:25: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:9:28: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation<@A K> { +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:9:23: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue<@A K> { +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:8:30: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + DuplicateAnnotationValue<@A(value = 2, value = 1) ?> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + DuplicateTypeAnno<@A @A ?> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:21: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:24: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + InvalidLocation<@A ?> l; +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + MissingAnnotationValue<@A ?> l; +} + +@interface A { int field(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,37 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse + * @author Mahmood Ali + * @compile/fail/ref=Constructor.out -XDrawDiagnostics Constructor.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class Constructor { + // Constructor result type use annotation + @A Constructor() { } + + // Not type parameter annotation + @B Constructor(int x) { } + + // TODO add err: no "this" receiver parameter for constructors + // Constructor(@A Constructor this, Object o) { } + + // TODO: support Outer.this. +} + +class Constructor2 { + class Inner { + // OK + @A Inner() { } + } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +@Target(ElementType.TYPE_PARAMETER) +@interface B { } + diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +Constructor.java:17:3: compiler.err.annotation.type.not.applicable +1 error \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,74 @@ +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.TYPE_PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/* + * Copyright (c) 2009 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 Class literals are not type uses and cannot be annotated + * @author Werner Dietl + * @compile/fail/ref=DotClass.out -XDrawDiagnostics DotClass.java + */ + +@Target({TYPE_USE, TYPE_PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +@interface B { int value(); } + +class T0x1E { + void m0x1E() { + Class c = @A Object.class; + } + + Class c = @A String.class; + + Class as = @A String.class; +} + +class ClassLiterals { + public static void main(String[] args) { + if (String.class != @A String.class) throw new Error(); + if (@A int.class != int.class) throw new Error(); + if (@A int.class != Integer.TYPE) throw new Error(); + if (@A int @B(0) [].class != int[].class) throw new Error(); + + if (String[].class != @A String[].class) throw new Error(); + if (String[].class != String @A [].class) throw new Error(); + if (@A int[].class != int[].class) throw new Error(); + if (@A int @B(0) [].class != int[].class) throw new Error(); + } + + Object classLit1 = @A String @C [] @B(0) [].class; + Object classLit2 = @A String @C [] [].class; + Object classLit3 = @A String [] @B(0) [].class; + Object classLit4 = String [] @B(0) [].class; + Object classLit5 = String @C [] [].class; + Object classLit6 = String [] [].class; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,17 @@ +DotClass.java:47:42: compiler.err.no.annotations.on.dot.class +DotClass.java:50:33: compiler.err.no.annotations.on.dot.class +DotClass.java:52:52: compiler.err.no.annotations.on.dot.class +DotClass.java:57:44: compiler.err.no.annotations.on.dot.class +DotClass.java:58:26: compiler.err.no.annotations.on.dot.class +DotClass.java:59:26: compiler.err.no.annotations.on.dot.class +DotClass.java:60:35: compiler.err.no.annotations.on.dot.class +DotClass.java:62:48: compiler.err.no.annotations.on.dot.class +DotClass.java:63:49: compiler.err.no.annotations.on.dot.class +DotClass.java:64:28: compiler.err.no.annotations.on.dot.class +DotClass.java:65:35: compiler.err.no.annotations.on.dot.class +DotClass.java:68:54: compiler.err.no.annotations.on.dot.class +DotClass.java:69:54: compiler.err.no.annotations.on.dot.class +DotClass.java:70:54: compiler.err.no.annotations.on.dot.class +DotClass.java:71:54: compiler.err.no.annotations.on.dot.class +DotClass.java:72:54: compiler.err.no.annotations.on.dot.class +16 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete array declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics IncompleteArray.java + */ +class IncompleteArray { + int @A [] @A var; +} + +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +IncompleteArray.java:9:13: compiler.err.illegal.start.of.type +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse and TypeParameter + * @author Mahmood Ali + * @compile/fail/ref=NotTypeParameter.out -XDrawDiagnostics NotTypeParameter.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod<@A K> { + @A void test() { } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +class TypeVariable<@B T> { + @B T test1() { return null; } + void test2(@B T p) {} +} + +@Target(ElementType.TYPE_PARAMETER) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,4 @@ +NotTypeParameter.java:13:3: compiler.err.annotation.type.not.applicable +NotTypeParameter.java:20:3: compiler.err.annotation.type.not.applicable +NotTypeParameter.java:21:14: compiler.err.annotation.type.not.applicable +3 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse + * @author Mahmood Ali + * @compile/fail/ref=NotTypeUse.out -XDrawDiagnostics NotTypeUse.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod { + @A void test() { } +} + +@Target(ElementType.TYPE) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +NotTypeUse.java:13:3: compiler.err.annotation.type.not.applicable +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,33 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse and TypeParameter + * @author Mahmood Ali + * @compile/fail/ref=VoidMethod.out -XDrawDiagnostics VoidMethod.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod { + // Invalid + @A void test1() { } + // The following is legal: + @B void test2() { } + // Invalid + @C void test3() { } + // The following is legal: + @D void test4() { } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +@Target({ElementType.TYPE_USE, ElementType.METHOD}) +@interface B { } + +@Target(ElementType.TYPE_PARAMETER) +@interface C { } + +@Target({ElementType.TYPE_PARAMETER, ElementType.METHOD}) +@interface D { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,3 @@ +VoidMethod.java:14:3: compiler.err.annotation.type.not.applicable +VoidMethod.java:18:3: compiler.err.annotation.type.not.applicable +2 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,81 @@ + +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary random tests for new locations + * @author Matt Papi + * @compile BasicTest.java + */ + +import java.lang.annotation.*; +import java.util.*; +import java.io.*; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface C {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface D {} + +/** + * Tests basic JSR 308 parser functionality. We don't really care about what + * the parse tree looks like, just that these annotations can be parsed. + */ +class BasicTest extends @B LinkedList implements @C List { + + void test() { + + // Handle annotated cast types + Object o = (@A Object) "foo"; + + // Handle annotated "new" expressions (except arrays; see ArrayTest) + String s = new @A String("bar"); + + boolean b = o instanceof @A Object; + + @A Map<@B List<@C String>, @D String> map = + new @A HashMap<@B List<@C String>, @D String>(); + + Class c2 = null; + } + + // Handle receiver annotations + // Handle annotations on a qualified identifier list + void test2(@C @D BasicTest this) throws @A IllegalArgumentException, @B IOException { + + } + + // Handle annotations on a varargs element type + void test3(@B Object @A... objs) { } + + void test4(@B Class<@C ?> @A ... clz) { } + + + // TODO: add more tests... nested classes, etc. +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: class extends/implements + * @author Mahmood Ali + * @compile ClassExtends.java + */ +abstract class MyClass extends @A ParameterizedClass<@B String> + implements @B CharSequence, @A ParameterizedInterface<@B String> { } + +interface MyInterface extends @A ParameterizedInterface<@A String>, + @B CharSequence { } + +class ParameterizedClass {} +interface ParameterizedInterface {} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B {} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: class type parameter bounds + * @author Mahmood Ali + * @compile ClassParameters.java + */ +class Unannotated { } + +class ExtendsBound { } +class ExtendsGeneric> { } +class TwoBounds { } + +class Complex1 { } +class Complex2 { } +class ComplexBoth { } + +class Outer { + void inner() { + class Unannotated { } + + class ExtendsBound { } + class ExtendsGeneric> { } + class TwoBounds { } + + class Complex1 { } + class Complex2 { } + class ComplexBoth { } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: constructor type args + * @author Mahmood Ali + * @compile ConstructorTypeArgs.java + */ + +class ConstructorTypeArgs { + void oneArg() { + new @A MyList<@A String>(); + new MyList<@A MyList<@B(0) String>>(); + } + + void twoArg() { + new MyMap(); + new MyMap<@A String, @B(0) MyList<@A String>>(); + } + + void withArraysIn() { + new MyList(); + new MyList<@A String @B(0) [] @A []>(); + + new MyMap<@A String[], @B(0) MyList<@A String> @A []>(); + } +} + +class MyList { } +class MyMap { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,76 @@ +/* + * 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.*; + +import java.io.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: exception parameters + * @author Werner Dietl + * @compile ExceptionParameters.java + */ + +class ExceptionParameters { + + void exception() { + try { + foobar(); + } catch (@A Exception e) { + e.toString(); + } + } + + void finalException() { + try { + foobar(); + } catch (final @B Exception e) { + e.toString(); + } + } + + void multiException1() { + try { + foobar(); + } catch (@A NullPointerException | @B IndexOutOfBoundsException e) { + e.toString(); + } + } + + void multiException2() { + try { + foobar(); + } catch (java.lang.@A NullPointerException | java.lang.@B IndexOutOfBoundsException e) { + e.toString(); + } + } + + void foobar() {} +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: expressions + * @author Mahmood Ali + * @compile Expressions.java + */ +class Expressions { + void instanceOf() { + Object o = null; + boolean a = o instanceof @A String; + boolean b = o instanceof @B(0) String; + } + + void instanceOfArray() { + Object o = null; + boolean a1 = o instanceof @A String []; + boolean a2 = o instanceof @B(0) String []; + + boolean b1 = o instanceof String @A []; + boolean b2 = o instanceof String @B(0) []; + } + + void objectCreation() { + new @A String(); + new @B(0) String(); + } + + void objectCreationArray() { + Object a1 = new @A String [] [] { }; + Object a2 = new @A String [1] []; + Object a3 = new @A String [1] [2]; + + Object b1 = new @A String @B(0) [] [] { }; + Object b2 = new @A String @B(0) [1] []; + Object b3 = new @A String @B(0) [1] [2]; + + Object c1 = new @A String [] @B(0) [] { }; + Object c2 = new @A String [1] @B(0) []; + Object c3 = new @A String [1] @B(0) [2]; + + Object d1 = new @A String @B(0) [] @B(0) [] { }; + Object d2 = new @A String @B(0) [1] @B(0) []; + Object d3 = new @A String @B(0) [1] @B(0) [2]; + + Object rand = new @A String @B(value = 0) [1] @B(value = 0) [2]; + + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: field type array/generics + * @author Mahmood Ali + * @compile Fields.java + */ + +class DefaultScope { + Parameterized unannotated; + Parameterized<@A String, String> firstTypeArg; + Parameterized secondTypeArg; + Parameterized<@A String, @B String> bothTypeArgs; + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized; + + @A String [] array1; + @A String @B [] array1Deep; + @A String [] [] array2; + @A String @A [] @B [] array2Deep; + String @A [] [] array2First; + String [] @B [] array2Second; + + // Old-style array syntax + String array2FirstOld @A []; + String array2SecondOld [] @B []; +} + +class ModifiedScoped { + public final Parameterized unannotated = null; + public final Parameterized<@A String, String> firstTypeArg = null; + public final Parameterized secondTypeArg = null; + public final Parameterized<@A String, @B String> bothTypeArgs = null; + + public final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized = null; + + public final @A String [] array1 = null; + public final @A String @B [] array1Deep = null; + public final @A String [] [] array2 = null; + public final @A String @A [] @B [] array2Deep = null; + public final String @A [] [] array2First = null; + public final String [] @B [] array2Second = null; +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: local variables array/generics + * @author Mahmood Ali + * @compile LocalVariables.java + */ + +class DefaultScope { + void parameterized() { + Parameterized unannotated; + Parameterized<@A String, String> firstTypeArg; + Parameterized secondTypeArg; + Parameterized<@A String, @B String> bothTypeArgs; + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized; + } + + void arrays() { + @A String [] array1; + @A String @B [] array1Deep; + @A String [] [] array2; + @A String @A [] @B [] array2Deep; + String @A [] [] array2First; + String [] @B [] array2Second; + } +} + +class ModifiedVars { + void parameterized() { + final Parameterized unannotated = null; + final Parameterized<@A String, String> firstTypeArg = null; + final Parameterized secondTypeArg = null; + final Parameterized<@A String, @B String> bothTypeArgs = null; + + final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized = null; + } + + void arrays() { + final @A String [] array1 = null; + final @A String @B [] array1Deep = null; + final @A String [] [] array2 = null; + final @A String @A [] @B [] array2Deep = null; + final String @A [] [] array2First = null; + final String [] @B [] array2Second = null; + } +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: method return type array/generics + * @author Mahmood Ali + * @compile MethodReturnType.java + */ + +class DefaultScope { + Parameterized unannotated() { return null; } + Parameterized<@A String, String> firstTypeArg() { return null; } + Parameterized secondTypeArg() { return null; } + Parameterized<@A String, @B String> bothTypeArgs() { return null; } + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized() { return null; } + + public @A String method() { return null; } + + @A String [] array1() { return null; } + @A String @B [] array1Deep() { return null; } + @A String [] [] array2() { return null; } + @A String @A [] @B [] array2Deep() { return null; } + String @A [] [] array2First() { return null; } + String [] @B [] array2Second() { return null; } + + // Old-style array syntax + String array2FirstOld() @A [] { return null; } + String array2SecondOld() [] @B [] { return null; } +} + +class ModifiedScoped { + public final Parameterized unannotated() { return null; } + public final Parameterized<@A String, String> firstTypeArg() { return null; } + public final Parameterized secondTypeArg() { return null; } + public final Parameterized<@A String, @B String> bothTypeArgs() { return null; } + + public final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized() { return null; } + + public final @A String [] array1() { return null; } + public final @A String @B [] array1Deep() { return null; } + public final @A String [] [] array2() { return null; } + public final @A String @A [] @B [] array2Deep() { return null; } + public final String @A [] [] array2First() { return null; } + public final String [] @B [] array2Second() { return null; } +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: method type args + * @author Mahmood Ali + * @compile MethodTypeArgs.java + */ + +class MethodTypeArgs { + void oneArg() { + this.<@A String>newList(); + this.<@A MyList<@B(0) String>>newList(); + + MethodTypeArgs.<@A String>newList(); + MethodTypeArgs.<@A MyList<@B(0) String>>newList(); + } + + void twoArg() { + this.newMap(); + this.<@A String, @B(0) MyList<@A String>>newMap(); + + MethodTypeArgs.newMap(); + MethodTypeArgs.<@A String, @B(0) MyList<@A String>>newMap(); + } + + void withArraysIn() { + this.newList(); + this.<@A String @B(0) [] @A []>newList(); + + this.<@A String[], @B(0) MyList<@A String> @A []>newMap(); + } + + static void newList() { } + static void newMap() { } +} + +class MyList { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: method type parameter bounds + * @author Mahmood Ali + * @compile MethodTypeParameters.java + */ + +class UnscopedUnmodified { + void methodExtends() {} + > void nestedExtends() {} + > void dual() {} + > void dualOneAnno() {} +} + +class PublicModifiedMethods { + public final void methodExtends() {} + public final > void nestedExtends() {} + public final > void dual() {} + public final > void dualOneAnno() {} +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008, 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 + * @ignore // syntax not sure yet. + * @bug 8006775 + * @summary new type annotation location: multicatch + * @author Werner Dietl + * @compile MultiCatch.java + */ + +class DefaultScope { + void exception01() { + try { + System.out.println("Hello 1!"); + } catch (@B NullPointerException | @C IllegalArgumentException e) { + e.toString(); + } + } + void exception02() { + try { + System.out.println("Hello 2!"); + } catch @A (@B NullPointerException | @C IllegalArgumentException e) { + e.toString(); + } + } +} + +class ModifiedVars { + /* + void exception() { + try { + arrays(); + } catch (final @A Exception e) { + e.toString(); + } + } + */ +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface C { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface D { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2008, 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.*; +import java.util.Map; + +/* + * @test + * @bug 8006775 + * @summary new type annotation location: nested types + * @author Werner Dietl + * @compile NestedTypes.java + */ +class Outer { + class Inner { + class Inner2 { + // m1a-c all have the same parameter type. + void m1a(@A Inner2 p1a) {} + void m1b(Inner.@A Inner2 p1b) {} + void m1c(Outer.Inner.@A Inner2 p1c) {} + // notice the difference to m1d + void m1d(@A Outer.Inner.Inner2 p1d) {} + + // m2a-b both have the same parameter type. + void m2a(@A Inner.Inner2 p2a) {} + void m2b(Outer.@A Inner.Inner2 p2b) {} + + // The location for @A is the same in m3a-c + void m3a(@A Outer p3a) {} + void m3b(@A Outer.Inner p3b) {} + void m3c(@A Outer.Inner.Inner2 p3c) {} + + // Test combinations + void m4a(@A Outer p3a) {} + void m4b(@A Outer. @B Inner p3b) {} + void m4c(@A Outer. @B Inner. @C Inner2 p3c) {} + } + } + + void m4a(@A Map p4a) {} + void m4b(Map.@B Entry p4c) {} + // Illegal: + // void m4b(@A Map.Entry p4b) {} + // void m4c(@A Map.@B Entry p4c) {} + + void m4c(Map.@B Entry p4d) {} + // Illegal: + // void m4d(@A Map.@B Entry p4d) {} + + void m4e(MyList p4e) {} + void m4f(MyList p4f) {} + // Illegal: + // void m4g(MyList<@A Map.Entry> p4e) {} + // void m4h(MyList<@A Map.@B Entry> p4f) {} + + class GInner { + class GInner2 {} + } + + static class Static {} + static class GStatic { + static class GStatic2 {} + } +} + +class Test1 { + // Outer.GStatic.GStatic2 gs; + Outer.GStatic.@A GStatic2 gsgood; + // TODO: add failing test + // Outer.@A GStatic.GStatic2 gsbad; + + MyList<@A Outer . @B Inner. @C Inner2> f; + @A Outer .GInner.GInner2 g; + + // TODO: Make sure that something like this fails gracefully: + // MyList pkg; + + @A Outer f1; + @A Outer . @B Inner f2 = f1.new @B Inner(); + // TODO: ensure type annos on new are stored. + @A Outer . @B GInner<@C Object> f3 = f1.new @B GInner<@C Object>(); + + MyList<@A Outer . @B GInner<@C MyList<@D Object>>. @E GInner2<@F Integer, @G Object>> f4; + // MyList.GInner2> f4clean; + + @A Outer . @B GInner<@C MyList<@D Object>>. @E GInner2<@F Integer, @G Object> f4top; + + MyList<@A Outer . @B GInner<@C MyList<@D Object @E[] @F[]>>. @G GInner2<@H Integer, @I Object> @J[] @K[]> f4arr; + + @A Outer . @B GInner<@C MyList<@D Object @E[] @F[]>>. @G GInner2<@H Integer, @I Object> @J[] @K[] f4arrtop; + + MyList f5; + // Illegal: + // MyList<@A Outer . @B Static> f5; + + Outer . @B Static f6; + // Illegal: + // @A Outer . @B Static f6; + + Outer . @Bv("B") GStatic<@Cv("C") String, @Dv("D") Object> f7; + // Illegal: + // @Av("A") Outer . @Bv("B") GStatic<@Cv("C") String, @Dv("D") Object> f7; + + Outer . @Cv("Data") Static f8; + // Illegal: + // @A Outer . @Cv("Data") Static f8; + + MyList f9; + // Illegal: + // MyList<@A Outer . @Cv("Data") Static> f9; +} + +class Test2 { + void m() { + @A Outer f1 = null; + @A Outer.@B Inner f2 = null; + Outer.@B Static f3 = null; + // Illegal: + // @A Outer.@B Static f3 = null; + @A Outer.@C Inner f4 = null; + + Outer . @B Static f5 = null; + Outer . @Cv("Data") Static f6 = null; + MyList f7 = null; + } +} + +class Test3 { + void monster(@A Outer p1, + @A Outer.@B Inner p2, + Outer.@B Static p3, + @A Outer.@Cv("Test") Inner p4, + Outer . @B Static p5, + Outer . @Cv("Data") Static p6, + MyList p7) { + } +} + +class Test4 { + void m() { + @A Outer p1 = new @A Outer(); + @A Outer.@B Inner p2 = p1.new @B Inner(); + // Illegal: + // @A Outer.@B Static p3 = new @A Outer.@B Static(); + // Object o3 = new @A Outer.@B Static(); + + @A Outer.@Cv("Test") Inner p4 = p1.new @Cv("Test") Inner(); + Outer . @B Static p5 = new Outer . @B Static(); + Outer . @Cv("Data") Static p6 = new Outer . @Cv("Data") Static(); + MyList p7 = new MyList(); + } +} + +class MyList { } + + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface C { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface D { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface E { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface F { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface G { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface H { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface I { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface J { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface K { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Av { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Bv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Cv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Dv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Ev { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Fv { String value(); } + diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: parameter type array/generics + * @author Mahmood Ali + * @compile Parameters.java + */ + +class Parameters { + void unannotated(Parameterized a) {} + void firstTypeArg(Parameterized<@A String, String> a) {} + void secondTypeArg(Parameterized a) {} + void bothTypeArgs(Parameterized<@A String, @B String> both) {} + + void nestedParameterized(Parameterized<@A Parameterized<@A String, @B String>, @B String> a) {} + + void array1(@A String [] a) {} + void array1Deep(@A String @B [] a) {} + void array2(@A String [] [] a) {} + void array2Deep(@A String @A [] @B [] a) {} + void array2First(String @A [] [] a) {} + void array2Second(String [] @B [] a) {} +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: receivers + * @author Mahmood Ali, Werner Dietl + * @compile Receivers.java + */ +class DefaultUnmodified { + void plain(@A DefaultUnmodified this) { } + void generic(@A DefaultUnmodified this) { } + void withException(@A DefaultUnmodified this) throws Exception { } + String nonVoid(@A DefaultUnmodified this) { return null; } + void accept(@A DefaultUnmodified this, T r) throws Exception { } +} + +class PublicModified { + public final void plain(@A PublicModified this) { } + public final void generic(@A PublicModified this) { } + public final void withException(@A PublicModified this) throws Exception { } + public final String nonVoid(@A PublicModified this) { return null; } + public final void accept(@A PublicModified this, T r) throws Exception { } +} + +class WithValue { + void plain(@B("m") WithValue this) { } + void generic(@B("m") WithValue this) { } + void withException(@B("m") WithValue this) throws Exception { } + String nonVoid(@B("m") WithValue this) { return null; } + void accept(@B("m") WithValue this, T r) throws Exception { } +} + +class WithFinal { + void plain(final @B("m") WithFinal this) { } + void generic(final @B("m") WithFinal this) { } + void withException(final @B("m") WithFinal this) throws Exception { } + String nonVoid(final @B("m") WithFinal this) { return null; } + void accept(final @B("m") WithFinal this, T r) throws Exception { } +} + +class WithBody { + Object f; + + void field(@A WithBody this) { + this.f = null; + } + void meth(@A WithBody this) { + this.toString(); + } +} + +class Generic1 { + void test1(Generic1 this) {} + void test2(@A Generic1 this) {} + void test3(Generic1<@A X> this) {} + void test4(@A Generic1<@A X> this) {} +} + +class Generic2<@A X> { + void test1(Generic2 this) {} + void test2(@A Generic2 this) {} + void test3(Generic2<@A X> this) {} + void test4(@A Generic2<@A X> this) {} +} + +class Generic3 { + void test1(Generic3 this) {} + void test2(@A Generic3 this) {} + void test3(Generic3<@A X> this) {} + void test4(@A Generic3<@A X> this) {} +} + +class Generic4 { + void test1(Generic4 this) {} + void test2(@A Generic4 this) {} + void test3(Generic4<@A X> this) {} + void test4(@A Generic4<@A X> this) {} +} + +class Outer { + class Inner { + void none(Outer.Inner this) {} + void outer(@A Outer.Inner this) {} + void inner(Outer. @B("i") Inner this) {} + void both(@A Outer.@B("i") Inner this) {} + + void innerOnlyNone(Inner this) {} + void innerOnly(@A Inner this) {} + } +} + +class GenericOuter { + class GenericInner { + void none(GenericOuter.GenericInner this) {} + void outer(@A GenericOuter.GenericInner this) {} + void inner(GenericOuter. @B("i") GenericInner this) {} + void both(@A GenericOuter.@B("i") GenericInner this) {} + + void innerOnlyNone(GenericInner this) {} + void innerOnly(@A GenericInner this) {} + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,127 @@ +/* + * 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 8006775 + * @summary repeating type annotations are possible + * @author Werner Dietl + * @compile/fail/ref=RepeatingTypeAnnotations.out -XDrawDiagnostics RepeatingTypeAnnotations.java + */ + +class RepeatingTypeAnnotations { + // Fields + @RTA @RTA Object fr1 = null; + Object fr2 = new @RTA @RTA Object(); + // error + Object fs = new @TA @TA Object(); + // error + Object ft = new @TA @TA Object(); + Object fe = new @TA @TA Object(); + + // Local variables + Object foo() { + Object o = new @RTA @RTA Object(); + o = new @TA @RTA @RTA Object(); + o = new @RTA @TA @RTA Object(); + // error + o = new @RTA @TA @RTA @TA Object(); + // error + return new @TA @TA Object(); + } + + // Instance creation + Object bar() { + Object o = new @RTA @RTA MyList<@RTA @RTA Object>(); + o = new @TA @RTA MyList<@TA @RTA Object>(); + o = new @TA @RTA @RTA MyList<@RTA @TA @RTA Object>(); + // error + o = new @TA @TA MyList<@RTA @RTA Object>(); + // error + o = new @RTA @RTA MyList<@TA @TA Object>(); + // error + return new @TA @TA MyList<@RTA @RTA Object>(); + } + + // More tests + void oneArg() { + Object o = new @RTA @RTA Object(); + // error + o = new @TA @TA Object(); + o = new @RTA @TA @RTA Object(); + + o = new MyList<@RTA @RTA Object>(); + // error + o = new MyList<@TA @TA Object>(); + // error + o = new @TA @TA MyList<@TA @TA Object>(); + // error + this.<@TA @TA String>newList(); + + this.<@RTA @RTA MyList<@RTA @RTA String>>newList(); + // error + this.<@TA @TA MyList<@TA @TA String>>newList(); + + o = (@RTA @RTA MyList<@RTA @RTA Object>) o; + // error + o = (@TA @TA MyList<@TA @TA Object>) o; + + this.<@RTA @RTA String, @RTA @RTA Object>newMap(); + // error + this.<@TA @TA String, @TA @TA Object>newMap(); + + this.<@RTA @RTA String @RTA @RTA []>newList(); + // error + this.<@TA @TA String @TA @TA []>newList(); + + this.<@RTA @RTA String @RTA @RTA [] @RTA @RTA [], MyList<@RTA @RTA String> @RTA @RTA []>newMap(); + // error + this. @TA @TA []>newMap(); + } + + static void newList() { } + static void newMap() { } +} + +class MyList { } + + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TAs { + TA[] value(); +} + +@Repeatable(RTAs.class) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface RTA { } + +@ContainerFor(RTA.class) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface RTAs { + RTA[] value(); +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,53 @@ +RepeatingTypeAnnotations.java:39:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:39:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:41:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:41:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:42:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:42:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:50:22: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:50:31: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:52:20: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:52:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:61:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:61:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:63:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:63:38: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:65:20: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:65:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:72:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:72:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:77:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:77:28: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:32: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:36: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:81:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:81:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:30: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:14: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:18: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:29: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:33: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:31: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:35: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:30: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:22: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:26: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:33: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:37: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:68: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:72: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:52: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:56: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +- compiler.note.unchecked.filename: RepeatingTypeAnnotations.java +- compiler.note.unchecked.recompile +50 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,46 @@ +/* + * 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.*; + +import java.io.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: resource variables + * @author Werner Dietl + * @compile ResourceVariables.java + */ + +class ResourceVariables { + void m() throws Exception { + try (@A InputStream is = new @B FileInputStream("xxx")) { + } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: throw clauses + * @author Mahmood Ali + * @compile Throws.java + */ +class DefaultUnmodified { + void oneException() throws @A Exception {} + void twoExceptions() throws @A RuntimeException, @A Exception {} +} + +class PublicModified { + public final void oneException(String a) throws @A Exception {} + public final void twoExceptions(String a) throws @A RuntimeException, @A Exception {} +} + +class WithValue { + void oneException() throws @B("m") Exception {} + void twoExceptions() throws @B(value="m") RuntimeException, @A Exception {} +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,50 @@ +/* + * 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. + */ + +import java.lang.annotation.*; +import java.util.Map; + +/* + * @test + * @bug 8006775 + * @summary type annotation location: top level blocks + * @author Werner Dietl + * @compile TopLevelBlocks.java + */ + +class TopLevelBlocks { + static Object f; + + { + f = new @A Object(); + } + + static final Object sf; + + static { + sf = new @A Object(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: type casts + * @author Mahmood Ali + * @compile TypeCasts.java + */ +class TypeCasts { + void methodA() { + String s = (@A String) null; + Object o = (@A Class<@A String>) null; + } + + void methodB() { + String s = (@B("m") String) null; + Object o = (@B("m") Class<@B("m") String>) null; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: class and method type parameters + * @author Mahmood Ali + * @compile TypeParameters.java + */ + +class Unannotated { } +class OneAnnotated<@A K> { } +class TwoAnnotated<@A K, @A V> { } +class SecondAnnotated { } + +class TestMethods { + void unannotated() { } + <@A K> void oneAnnotated() { } + <@A K, @B("m") V> void twoAnnotated() { } + void secondAnnotated() { } +} + +class UnannotatedB { } +class OneAnnotatedB<@B("m") K> { } +class TwoAnnotatedB<@B("m") K, @B("m") V> { } +class SecondAnnotatedB { } + +class OneAnnotatedC<@C K> { } +class TwoAnnotatedC<@C K, @C V> { } +class SecondAnnotatedC { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } +@Target(ElementType.TYPE_USE) +@interface C { } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,46 @@ + +/* + * Copyright (c) 2008 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 + * @summary test acceptance of varargs annotations + * @author Mahmood Ali + * @compile Varargs.java + */ + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} + +class Varargs { + + // Handle annotations on a varargs element type + void varargPlain(Object @A... objs) { + + } + + void varargGeneric(Class @A ... clz) { + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008, 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 6843077 8006775 + * @summary new type annotation location: wildcard bound + * @author Mahmood Ali + * @compile Wildcards.java + */ +class BoundTest { + void wcExtends(MyList l) { } + void wcSuper(MyList l) { } + + MyList returnWcExtends() { return null; } + MyList returnWcSuper() { return null; } + MyList> complex() { return null; } +} + +class BoundWithValue { + void wcExtends(MyList l) { } + void wcSuper(MyList l) { } + + MyList returnWcExtends() { return null; } + MyList returnWcSuper() { return null; } + MyList> complex() { return null; } +} + +class SelfTest { + void wcExtends(MyList<@A ?> l) { } + void wcSuper(MyList<@A ?> l) { } + + MyList<@A ?> returnWcExtends() { return null; } + MyList<@A ?> returnWcSuper() { return null; } + MyList<@A ? extends @A MyList<@B("m") ?>> complex() { return null; } +} + +class SelfWithValue { + void wcExtends(MyList<@B("m") ?> l) { } + void wcSuper(MyList<@B(value="m") ?> l) { } + + MyList<@B("m") ?> returnWcExtends() { return null; } + MyList<@B(value="m") ?> returnWcSuper() { return null; } + MyList<@B("m") ? extends MyList<@B("m") ? super String>> complex() { return null; } +} + +class MyList { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 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.util.HashSet; +import java.util.Set; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.ElementFilter; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.JavaCompiler.CompileState; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Context; + +/* + * @test + * @summary test that package annotations are available to type processors. + * This class implements the functionality of a type processor, as previously + * embodied by the AbstractTypeProcessor class. + * + * @author Mahmood Ali + * @author Werner Dietl + * + * @compile PackageProcessor.java + * @compile -cp . -processor PackageProcessor mypackage/Anno.java mypackage/MyClass.java mypackage/package-info.java + */ + +@SupportedAnnotationTypes("*") +public class PackageProcessor extends AbstractProcessor { + + private final AttributionTaskListener listener = new AttributionTaskListener(); + private final Set elements = new HashSet(); + + @Override + public final void init(ProcessingEnvironment env) { + super.init(env); + JavacTask.instance(env).addTaskListener(listener); + Context ctx = ((JavacProcessingEnvironment)processingEnv).getContext(); + JavaCompiler compiler = JavaCompiler.instance(ctx); + compiler.shouldStopPolicyIfNoError = CompileState.max(compiler.shouldStopPolicyIfNoError, + CompileState.FLOW); + } + + @Override + public final boolean process(Set annotations, + RoundEnvironment roundEnv) { + for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) { + elements.add(elem.getQualifiedName()); + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private final class AttributionTaskListener implements TaskListener { + @Override + public void started(TaskEvent e) { } + + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.ANALYZE) + return; + + if (!elements.remove(e.getTypeElement().getQualifiedName())) + return; + + if (e.getTypeElement().getSimpleName().contentEquals("MyClass")) { + Element owner = e.getTypeElement().getEnclosingElement(); + if (owner.getKind() != ElementKind.PACKAGE) + throw new RuntimeException("class owner should be a package: " + owner); + if (owner.getAnnotationMirrors().size() != 1) + throw new RuntimeException("the owner package should have one annotation: " + owner); + } + } + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 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. + */ +package mypackage; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Retention; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Anno {} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 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. + */ +package mypackage; + +public class MyClass {} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 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. + */ + +@mypackage.Anno +package mypackage; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for class extends clauses + * @compile -g Driver.java ReferenceInfoUtil.java ClassExtends.java + * @run main Driver ClassExtends + */ +public class ClassExtends { + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + }) + public String regularClass() { + return "class Test extends @TA Object implements Cloneable, @TB Runnable {" + + " public void run() { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + }) + public String regularClassExtendsParametrized() { + return "class Test extends HashMap<@TA String, String> implements Cloneable, Map{ } "; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + }) + public String abstractClass() { + return "abstract class Test extends @TA Date implements Cloneable, @TB Runnable {" + + " public void run() { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + }) + public String abstractClassExtendsParametrized() { + return "abstract class Test extends HashMap<@TA String, String> implements Cloneable, Map{ } "; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + public String regularInterface() { + return "interface Test extends Cloneable, @TB Runnable { }"; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + public String regularInterfaceExtendsParametrized() { + return "interface Test extends Cloneable, Map{ } "; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + public String regularEnum() { + return "enum Test implements Cloneable, @TB Runnable { TEST; public void run() { } }"; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 0 }) + public String regularEnumExtendsParametrized() { + return + "enum Test implements Cloneable, Comparator<@TB String> { TEST; " + + "public int compare(String a, String b) { return 0; }}"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for class type parameters + * @compile -g Driver.java ReferenceInfoUtil.java ClassTypeParam.java + * @run main Driver ClassTypeParam + */ +public class ClassTypeParam { + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass() { + return "class Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass2() { + return "class Test<@TA K extends @TB Date, @TC V extends @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String regularClassParameterized() { + return "class Test, V extends @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String regularClassParameterized2() { + return "class Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClass() { + return "abstract class Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0) + }) + public String abstractClassParameterized() { + return "abstract class Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularInterface() { + return "interface Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String regularInterfaceParameterized() { + return "interface Test, V extends @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String regularInterfaceParameterized2() { + return "interface Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String useInReturn1() { + return "class Test { @TA T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0}) + public String useInReturn2() { + return "class Test { Class<@TA T> m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam1() { + return "class Test { void m(Class<@TA T> p) { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam2() { + return "class Test { void m(Class<@TA Object> p) { throw new RuntimeException(); } }"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for constructor results + * @compile -g Driver.java ReferenceInfoUtil.java Constructors.java + * @run main Driver Constructors + */ +public class Constructors { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + public String regularClass() { + return "class Test { @TA Test() {}" + + " @TB Test(@TC int b) {} }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + @TestClass("Test$Inner") + public String innerClass() { + return "class Test { class Inner {" + + " @TA Inner() {}" + + " @TB Inner(@TC int b) {}" + + " } }"; + } + + /* TODO: Outer.this annotation support. + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RECEIVER), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_RECEIVER), + @TADescription(annotation = "TD", type = METHOD_RETURN), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + @TestClass("Test$Inner") + public String innerClass2() { + return "class Test { class Inner {" + + " @TB Inner(@TA Test Test.this) {}" + + " @TD Inner(@TC Test Test.this, @TE int b) {}" + + " } }"; + } + */ +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2009 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.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.TypeAnnotation.TargetType; + +public class Driver { + + private static final PrintStream out = System.out; + + public static void main(String[] args) throws Exception { + if (args.length == 0 || args.length > 1) + throw new IllegalArgumentException("Usage: java Driver "); + String name = args[0]; + Class clazz = Class.forName(name); + new Driver().runDriver(clazz.newInstance()); + } + + protected void runDriver(Object object) throws Exception { + int passed = 0, failed = 0; + Class clazz = object.getClass(); + out.println("Tests for " + clazz.getName()); + + // Find methods + for (Method method : clazz.getMethods()) { + Map expected = expectedOf(method); + if (expected == null) + continue; + if (method.getReturnType() != String.class) + throw new IllegalArgumentException("Test method needs to return a string: " + method); + String testClass = testClassOf(method); + + try { + String compact = (String)method.invoke(object); + String fullFile = wrap(compact); + ClassFile cf = compileAndReturn(fullFile, testClass); + List actual = ReferenceInfoUtil.extendedAnnotationsOf(cf); + ReferenceInfoUtil.compare(expected, actual, cf); + out.println("PASSED: " + method.getName()); + ++passed; + } catch (Throwable e) { + out.println("FAILED: " + method.getName()); + out.println(" " + e.toString()); + ++failed; + } + } + + out.println(); + int total = passed + failed; + out.println(total + " total tests: " + passed + " PASSED, " + failed + " FAILED"); + + out.flush(); + + if (failed != 0) + throw new RuntimeException(failed + " tests failed"); + } + + private Map expectedOf(Method m) { + TADescription ta = m.getAnnotation(TADescription.class); + TADescriptions tas = m.getAnnotation(TADescriptions.class); + + if (ta == null && tas == null) + return null; + + Map result = + new HashMap(); + + if (ta != null) + result.putAll(expectedOf(ta)); + + if (tas != null) { + for (TADescription a : tas.value()) { + result.putAll(expectedOf(a)); + } + } + + return result; + } + + private Map expectedOf(TADescription d) { + String annoName = d.annotation(); + + TypeAnnotation.Position p = new TypeAnnotation.Position(); + p.type = d.type(); + if (d.offset() != NOT_SET) + p.offset = d.offset(); + if (d.lvarOffset().length != 0) + p.lvarOffset = d.lvarOffset(); + if (d.lvarLength().length != 0) + p.lvarLength = d.lvarLength(); + if (d.lvarIndex().length != 0) + p.lvarIndex = d.lvarIndex(); + if (d.boundIndex() != NOT_SET) + p.bound_index = d.boundIndex(); + if (d.paramIndex() != NOT_SET) + p.parameter_index = d.paramIndex(); + if (d.typeIndex() != NOT_SET) + p.type_index = d.typeIndex(); + if (d.exceptionIndex() != NOT_SET) + p.exception_index = d.exceptionIndex(); + if (d.genericLocation().length != 0) { + p.location = TypeAnnotation.Position.getTypePathFromBinary(wrapIntArray(d.genericLocation())); + } + + return Collections.singletonMap(annoName, p); + } + + private List wrapIntArray(int[] ints) { + List list = new ArrayList(ints.length); + for (int i : ints) + list.add(i); + return list; + } + + private String testClassOf(Method m) { + TestClass tc = m.getAnnotation(TestClass.class); + if (tc != null) { + return tc.value(); + } else { + return "Test"; + } + } + + private ClassFile compileAndReturn(String fullFile, String testClass) throws Exception { + File source = writeTestFile(fullFile); + File clazzFile = compileTestFile(source, testClass); + return ClassFile.read(clazzFile); + } + + protected File writeTestFile(String fullFile) throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(fullFile); + out.close(); + return f; + } + + protected File compileTestFile(File f, String testClass) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path; + if (f.getParent() != null) { + path = f.getParent(); + } else { + path = ""; + } + + return new File(path + testClass + ".class"); + } + + private String wrap(String compact) { + StringBuilder sb = new StringBuilder(); + + // Automatically import java.util + sb.append("\nimport java.util.*;"); + sb.append("\nimport java.lang.annotation.*;"); + + sb.append("\n\n"); + boolean isSnippet = !(compact.startsWith("class") + || compact.contains(" class")) + && !compact.contains("interface") + && !compact.contains("enum"); + if (isSnippet) + sb.append("class Test {\n"); + + sb.append(compact); + sb.append("\n"); + + if (isSnippet) + sb.append("}\n\n"); + + if (isSnippet) { + // Have a few common nested types for testing + sb.append("class Outer { class Inner {} }"); + sb.append("class SOuter { static class SInner {} }"); + sb.append("class GOuter { class GInner {} }"); + } + + // create A ... F annotation declarations + sb.append("\n@interface A {}"); + sb.append("\n@interface B {}"); + sb.append("\n@interface C {}"); + sb.append("\n@interface D {}"); + sb.append("\n@interface E {}"); + sb.append("\n@interface F {}"); + + // create TA ... TF proper type annotations + sb.append("\n"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TB {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TC {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TD {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TE {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TF {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TG {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TH {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TI {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TJ {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TK {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TL {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TM {}"); + + // create RTA, RTAs, RTB, RTBs for repeating type annotations + sb.append("\n"); + sb.append("\n@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}"); + sb.append("\n@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}"); + + sb.append("\n@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }"); + sb.append("\n@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }"); + + sb.append("\n@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})"); + sb.append("\n@interface Decl {}"); + + return sb.toString(); + } + + public static final int NOT_SET = -888; + +} + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TADescription { + String annotation(); + + TargetType type(); + int offset() default Driver.NOT_SET; + int[] lvarOffset() default { }; + int[] lvarLength() default { }; + int[] lvarIndex() default { }; + int boundIndex() default Driver.NOT_SET; + int paramIndex() default Driver.NOT_SET; + int typeIndex() default Driver.NOT_SET; + int exceptionIndex() default Driver.NOT_SET; + + int[] genericLocation() default {}; +} + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TADescriptions { + TADescription[] value() default {}; +} + +/** + * The name of the class that should be analyzed. + * Should only need to be provided when analyzing inner classes. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TestClass { + String value() default "Test"; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,57 @@ +/* + * 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 + * @summary Test population of reference info for exception parameters + * @author Werner Dietl + * @compile -g Driver.java ReferenceInfoUtil.java ExceptionParameters.java + * @run main Driver ExceptionParameters + */ +public class ExceptionParameters { + + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0) + public String exception() { + return "void exception() { try { new Object(); } catch(@TA Exception e) { } }"; + } + + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0) + public String finalException() { + return "void finalException() { try { new Object(); } catch(final @TA 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 multipleExceptions() { + return "void multipleExceptions() { " + + "try { new Object(); } catch(@TA Exception e) { }" + + "try { new Object(); } catch(@TB Exception e) { }" + + "try { new Object(); } catch(@TC Exception e) { }" + + " }"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for field + * @compile -g Driver.java ReferenceInfoUtil.java Fields.java + * @run main Driver Fields + */ +public class Fields { + + // field types + @TADescription(annotation = "TA", type = FIELD) + public String fieldAsPrimitive() { + return "@TA int test;"; + } + + @TADescription(annotation = "TA", type = FIELD) + public String fieldAsObject() { + return "@TA Object test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String fieldAsParametrized() { + return "@TA Map<@TB String, @TC List<@TD String>> test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 0, 0, 0, 0 }) + }) + public String fieldAsArray() { + return "@TC String @TA [] @TB [] test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 0, 0, 0, 0 }) + }) + public String fieldAsArrayOld() { + return "@TC String test @TA [] @TB [];"; + } + + @TADescriptions({}) + public String fieldWithDeclarationAnnotatin() { + return "@Decl String test;"; + } + + @TADescriptions({}) + public String fieldWithNoTargetAnno() { + return "@A String test;"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = FIELD) + public String interfacefieldAsObject() { + return "interface Test { @TA String test = null; }"; + } + + @TADescription(annotation = "TA", type = FIELD) + public String abstractfieldAsObject() { + return "abstract class Test { @TA String test; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String interfacefieldAsParametrized() { + return "interface Test { @TA Map<@TB String, @TC List<@TD String>> test = null; }"; + } + + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String staticFieldAsParametrized() { + return "static @TA Map<@TB String, @TC List<@TD String>> test;"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test that the examples from the manual are stored as expected + * @compile -g Driver.java ReferenceInfoUtil.java FromSpecification.java + * @run main Driver FromSpecification + */ +public class FromSpecification { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 2, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1, 3, 0}, paramIndex = 0) + }) + public String testSpec1() { + return "void test(@TA Map<@TB ? extends @TC String, @TD List<@TE Object>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 0, 0}, paramIndex = 0) + }) + public String testSpec2() { + return "void test(@TI String @TF [] @TG [] @TH [] a) { }"; + } + + // Note first "1, 0" for top-level class Test. + @TADescriptions({ + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TL", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TM", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testSpec3() { + return "class Test { class O1 { class O2 { class O3 { class NestedStatic {} } } }" + + "void test(@TM O1.@TL O2.@TK O3.@TJ NestedStatic a) { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1, 3, 0}, paramIndex = 0) + }) + public String testSpec4() { + return "void test(@TA Map<@TB Comparable<@TF Object @TC [] @TD [] @TE []>, @TG List<@TH String>> a) { }"; + } + + // Note first "1, 0" for top-level class Test. + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testSpec5() { + return "class Test { class O1 { class O2 { class O3 { class Nested {} } } }" + + "void test(@TH O1.@TE O2<@TF String, @TG String>.@TD O3.@TA Nested<@TB String, @TC String> a) { } }"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for method parameters + * @compile -g Driver.java ReferenceInfoUtil.java MethodParameters.java + * @run main Driver MethodParameters + */ +public class MethodParameters { + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + public String methodParamAsPrimitive() { + return "void test(@TA int a) { }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + public String methodParamAsObject() { + return "void test(Object b, @TA Object a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0) + }) + public String methodParamAsParametrized() { + return "void test(@TA Map<@TB String, @TC List<@TD String>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 1, 2, 0 }, paramIndex = 0) + }) + public String methodParamAsWildcard() { + return "void test(@TA Map<@TB ? extends @TC String," + + " @TD List<@TE ? extends @TF Map<@TG ? super @TH String," + + " @TI ? extends @TJ Object>>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsArray() { + return "void test(Object b, @TC String @TA [] @TB [] a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsVararg() { + return "void test(Object b, @TC String @TA [] @TB ... a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsFQVararg() { + return "void test(Object b, java.lang.@TC String @TA [] @TB ... a) { }"; + } + + @TADescriptions({}) + public String methodWithDeclarationAnnotatin() { + return "void test(@Decl String a) { }"; + } + + @TADescriptions({}) + public String methodWithNoTargetAnno() { + return "void test(@A String a) { }"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + public String interfacemethodParamAsObject() { + return "interface Test { void test(@TA Object a); }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 2) + public String abstractmethodParamAsObject() { + return "abstract class Test { abstract void test(Object b, Object c, @TA Object a); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0) + }) + public String interfacemethodParamAsParametrized() { + return "interface Test { void test(@TA Map<@TB String, @TC List<@TD String>> a); }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for method receivers + * @compile -g Driver.java ReferenceInfoUtil.java MethodReceivers.java + * @run main Driver MethodReceivers + */ +public class MethodReceivers { + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String regularMethod() { + return "class Test { void test(@TA Test this) { } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String abstractMethod() { + return "abstract class Test { abstract void test(@TA Test this); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String interfaceMethod() { + return "interface Test { void test(@TA Test this); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String regularWithThrows() { + return "class Test { void test(@TA Test this) throws Exception { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RECEIVER, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RECEIVER, + genericLocation = {1, 0}) + }) + @TestClass("TestOuter$TestInner") + public String nestedtypes1() { + return "class TestOuter { class TestInner { void test(@TA TestOuter. @TB TestInner this) { } } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER, + genericLocation = {}) + @TestClass("TestOuter$TestInner") + public String nestedtypes2() { + return "class TestOuter { class TestInner { void test(@TA TestOuter.TestInner this) { } } }"; + } + + @TADescription(annotation = "TB", type = METHOD_RECEIVER, + genericLocation = {1, 0}) + @TestClass("TestOuter$TestInner") + public String nestedtypes3() { + return "class TestOuter { class TestInner { void test(TestOuter. @TB TestInner this) { } } }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for method return + * @compile -g Driver.java ReferenceInfoUtil.java MethodReturns.java + * @run main Driver MethodReturns + */ +public class MethodReturns { + + // Method returns + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String methodReturnAsPrimitive() { + return "@TA int test() { return 0; }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String methodReturnAsObject() { + return "@TA Object test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 1, 3, 0 }) + }) + public String methodReturnAsParametrized() { + return "@TA Map<@TB String, @TC List<@TD String>> test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 0, 0, 0, 0 }) + }) + public String methodReturnAsArray() { + return "@TC String @TA [] @TB [] test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 0, 0, 0, 0 }) + }) + public String methodReturnAsArrayOld() { + return "@TC String test() @TA [] @TB [] { return null; }"; + } + + @TADescriptions({}) + public String methodWithDeclarationAnnotation() { + return "@Decl String test() { return null; }"; + } + + @TADescriptions({}) + public String methodWithNoTargetAnno() { + return "@A String test() { return null; }"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String interfaceMethodReturnAsObject() { + return "interface Test { @TA Object test(); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String abstractMethodReturnAsObject() { + return "abstract class Test { abstract @TA Object test(); }"; + } + + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 1, 3, 0 }) + }) + public String interfaceMethodReturnAsParametrized() { + return "interface Test { @TA Map<@TB String, @TC List<@TD String>> test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1, 2, 0 }) + }) + public String methodReturnAsNestedWildcard() { + return "Set<@TA ? extends @TB GOuter. @TC GInner<@TD String, @TE ? super @TF Object>> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 1, 2, 0 }) + }) + public String methodReturnAsNestedWildcard2() { + return "class GOuter { class GInner {} } " + + "class Test { Set.GInner<@TA K, @TB ? extends @TC Object>> entrySet() { return null; } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard3() { + return "Set. @TC GInner> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard4() { + return "Set. @TC GInner> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard5() { + return "Set entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard6() { + return "Set. @TC GInner<@TA String, @TB Object>> entrySet() { return null; }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for method exception clauses + * @compile -g Driver.java ReferenceInfoUtil.java MethodThrows.java + * @run main Driver MethodThrows + */ +public class MethodThrows { + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String regularMethod() { + return "class Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String abstractMethod() { + return "abstract class Test { abstract void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String interfaceMethod() { + return "interface Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for method type parameters + * @compile -g Driver.java ReferenceInfoUtil.java MethodTypeParam.java + * @run main Driver MethodTypeParam + */ +public class MethodTypeParam { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass() { + return "<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass2() { + return "<@TA K extends @TB Date, @TC V extends @TE Cloneable> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0) + }) + public String regularClassParameterized() { + return ", V extends @TF Object & @TC List<@TD List<@TE Object>>> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClass() { + return "abstract class Test { abstract <@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String abstractClassParameterized() { + return "abstract class Test { abstract , V extends @TF Object & @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String abstractClassParameterized2() { + return "abstract class Test { abstract , V extends @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClassParameterized3() { + return "abstract class Test { abstract , V extends @TB List> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularInterface() { + return "interface Test { <@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER, paramIndex = 1) + }) + public String regularInterfaceParameterized() { + return "interface Test { <@TH K extends @TG Object & @TA Map, @TI V extends @TF Object & @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER, paramIndex = 1) + }) + public String regularInterfaceParameterized2() { + return "interface Test { <@TF K extends @TA Map, @TG V extends @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String useInReturn1() { + return "class Test { @TA T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0}) + public String useInReturn2() { + return "class Test { Class<@TA T> m() { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_RETURN) + }) + public String useInReturn3() { + return "class Test { @TB T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam1() { + return "class Test { void m(Class<@TA T> p) { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam2() { + return "class Test { void m(Class<@TA Object> p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 2), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + public String useInParam3() { + return "interface IA {} " + + "interface IB {} " + + "interface IC {} " + + "class Test { & @TB IC> void m(@TC T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 2, + genericLocation = {}), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0) + }) + public String useInParam4() { + return "class Test {" + + " interface IA {} " + + " interface IB {} " + + " interface IC {} " + + " & @TB IC> void m(@TC T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0, 3, 0}), + }) + public String useInParam5() { + return "class Test {" + + " interface IA {} " + + " class CB {} " + + " > void m(T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {3, 0}) + }) + public String useInParam6() { + return "class Test {" + + " interface IA {} " + + " interface IB {} " + + " class CC {} " + + " interface ID {} " + + " <@TA T extends @TB Test.CC<@TC IA> & Test. @TD ID<@TE IA>> void m(T p) { throw new RuntimeException(); } }"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,56 @@ +/* + * 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 8006732 8006775 + * @ignore + * @summary Test population of reference info for multicatch exception parameters + * @author Werner Dietl + * @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java + * @run main Driver MultiCatch + */ +public class MultiCatch { + + @TADescriptions({ + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0), + @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1) + }) + public String multiCatch1() { + return "void multiCatch1() { " + + "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException e) { e.toString(); } }"; + } + + @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 multiCatch2() { + return "void multiCatch2() { " + + "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException | @TC IllegalArgumentException e) { e.toString(); } }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,834 @@ +/* + * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for nested types + * @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java + * @run main Driver NestedTypes + */ +public class NestedTypes { + + // method parameters + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam1() { + return "void test(@TA Outer.@TB Inner a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam1b() { + return "void test(List<@TA Outer.@TB Inner> a) { }"; + } + + // TODO: the tests that use @TA Map.Entry should fail, as + // Map cannot be annotated. + // We need some tests for the fully qualified name syntax. + /* + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0) + public String testParam1c() { + return "void test(java.util.@TA Map.Entry a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam1d() { + return "void test(java.util.@TA Map.@TB Entry a) { }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0) + public String testParam1e() { + return "void test(List a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam1f() { + return "void test(List a) { }"; + } + */ + + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0) + public String testParam1g() { + return "void test(List a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam2() { + return "void test(@TA GOuter.@TB GInner a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam2b() { + return "void test(List<@TA GOuter.@TB GInner> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0}, paramIndex = 0) + }) + public String testParam3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test(@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a) { }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0}, paramIndex = 0) + }) + public String testParam4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test(List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a) { }\n" + + "}"; + } + + + // Local variables + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal1a() { + return "void test() { @TA Outer.@TB Inner a = null; }"; + } + + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + public String testLocal1b() { + return "void test() { @TA Outer.Inner a = null; }"; + } + + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + public String testLocal1c() { + return "void test() { Outer.@TB Inner a = null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal2() { + return "void test() { @TA GOuter.@TB GInner a = null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TD", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TE", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TF", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TG", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TH", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TI", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TJ", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TK", type = LOCAL_VARIABLE, + genericLocation = {0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test() { @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a = null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TD", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TE", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TF", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TG", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TH", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TI", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TJ", type = LOCAL_VARIABLE, + genericLocation = {3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TK", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test() { List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a = null; }\n" + + "}"; + } + + + // fields + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + }) + public String testField1a() { + return "@TA Outer.@TB Inner a;"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}) + public String testField1b() { + return "@TA Outer.Inner a;"; + } + + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + public String testField1c() { + return "Outer.@TB Inner a;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + }) + public String testField2() { + return "@TA GOuter.@TB GInner a;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {0, 0, 0, 0}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = FIELD), + @TADescription(annotation = "TK", type = FIELD, + genericLocation = {0, 0}) + }) + public String testField3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a;\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = FIELD, + genericLocation = {3, 0}), + @TADescription(annotation = "TK", type = FIELD, + genericLocation = {3, 0, 0, 0}) + }) + public String testField4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a;\n" + + "}"; + } + + + // return types + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {1, 0}) + }) + public String testReturn1() { + return "@TA Outer.@TB Inner test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {1, 0}) + }) + public String testReturn2() { + return "@TA GOuter.@TB GInner test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = METHOD_RETURN), + @TADescription(annotation = "TK", type = METHOD_RETURN, + genericLocation = {0, 0}) + }) + public String testReturn3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = METHOD_RETURN, + genericLocation = {3, 0}), + @TADescription(annotation = "TK", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0}) + }) + public String testReturn4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {3, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 1}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 1, 3, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TJ", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 1, 0}), + }) + public String testReturn5() { + return "class GOuter {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA GOuter<@TB String, @TC List<@TD Object>> . @TE GInner<@TF List<@TG Object @TH[] @TI[]>>. @TJ GInner2> test() { return null; }\n" + + "}"; + } + + + // type parameters + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, paramIndex = 0, boundIndex = 0) + }) + public String testTypeparam1() { + return " X test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, paramIndex = 0, boundIndex = 0) + }) + public String testTypeparam2() { + return ".@TB GInner> X test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0, 0, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0, 3, 1}, + paramIndex = 0, boundIndex = 0), + }) + public String testTypeparam3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " >. @TG GInner2<@TH Integer, @TI Object>> X test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TJ", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TK", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0}, + paramIndex = 0, boundIndex = 1) + }) + public String testTypeparam4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " >. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]>> X test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 1}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 1, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TJ", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 1, 0}, paramIndex = 0, boundIndex = 1), + }) + public String testTypeparam5() { + return "class GOuter {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " > . @TE GInner<@TF List<@TG Object @TH[] @TI[]>>. @TJ GInner2>> X test() { return null; }\n" + + "}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + public String testUses1a() { + return "class Test { class Inner {} List<@TA Inner> f; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0}) + public String testUses1b() { + return "class Test { class Inner {} List<@TA Test.Inner> f; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2a() { + return "class Test { class Inner { class Inner2{} List<@TA Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2b() { + return "class Test { class Inner { class Inner2{} List<@TA Inner.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2c() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0}) + @TestClass("Test$Inner") + public String testUses2d() { + return "class Test{ class Inner { class Inner2{} List<@TA Test.Inner.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2e() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2f() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses3a() { + return "class Test { class Inner { class Inner2{}\n" + + " List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses3b() { + return "class Test { class Inner { class Inner2{}\n" + + " List f; }}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {3, 0}) + }) + public String testUses4() { + return "class Test { static class TInner {}\n" + + " @TA TInner f; \n" + + " List<@TB TInner> g; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 3, 1}) + @TestClass("Test$Inner") + public String testUses3c() { + return "class Test { class Inner { class Inner2{}\n" + + " List.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex=0) + public String testFullyQualified1() { + return "void testme(java.security.@TA ProtectionDomain protectionDomain) {}"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex=0, + genericLocation = {3, 0}) + public String testFullyQualified2() { + return "void testme(List protectionDomain) {}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + // Only classes count, not methods. + genericLocation = {1, 0, 1, 0}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + }) + @TestClass("Outer$Inner") + public String testMethodNesting1() { + return "class Outer {\n" + + " class Inner {\n" + + " void foo() {\n" + + " class MInner {}\n" + + " @TA Outer . @TB Inner l1 = null;\n" + + " @TC MInner l2 = null;\n" + + " }\n" + + "}}\n"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = NEW, + genericLocation = {}, + offset = 0), + @TADescription(annotation = "TB", type = NEW, + genericLocation = {1, 0}, + offset = 0), + @TADescription(annotation = "TC", type = NEW, + // Only classes count, not methods. + genericLocation = {1, 0, 1, 0}, + offset = 12), + }) + @TestClass("Outer$Inner") + public String testMethodNesting2() { + return "class Outer {\n" + + " class Inner {\n" + + " void foo() {\n" + + " class MInner {}\n" + + " Object o1 = new @TA Outer . @TB Inner();" + + " Object o2 = new @TC MInner();\n" + + " }\n" + + "}}\n"; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for new object creations + * @compile -g Driver.java ReferenceInfoUtil.java NewObjects.java + * @run main Driver NewObjects + */ +public class NewObjects { + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return new @TA 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 returnObjectGeneric() { + return "Object returnObjectGeneric() { return new @TA ArrayList<@TB String>(); }"; + } + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = new @TA 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, + genericLocation = { 3, 1 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectGeneric() { + return "void initObjectGeneric() { Object a = new @TA HashMap<@TB String, @TC String>(); }"; + } + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (null == new @TA 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 eqtestObjectGeneric() { + return "void eqtestObjectGeneric() { if (null == new @TA ArrayList<@TB String >()); }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2009 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.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.Field; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute; +import com.sun.tools.classfile.ConstantPool.InvalidIndex; +import com.sun.tools.classfile.ConstantPool.UnexpectedEntry; + +public class ReferenceInfoUtil { + + public static final int IGNORE_VALUE = -321; + + public static List extendedAnnotationsOf(ClassFile cf) { + List annos = new ArrayList(); + findAnnotations(cf, annos); + return annos; + } + + /////////////////// Extract type annotations ////////////////// + private static void findAnnotations(ClassFile cf, List annos) { + findAnnotations(cf, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, Attribute.RuntimeInvisibleTypeAnnotations, annos); + + for (Field f : cf.fields) { + findAnnotations(cf, f, annos); + } + for (Method m: cf.methods) { + findAnnotations(cf, m, annos); + } + } + + private static void findAnnotations(ClassFile cf, Method m, List annos) { + findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); + } + + private static void findAnnotations(ClassFile cf, Field m, List annos) { + findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, String name, List annos) { + 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; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, Method m, String name, List annos) { + 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; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, Field m, String name, List annos) { + 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; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + /////////////////// TA Position Builder /////////////////////// + /* TODO: comment out this dead code. Was this unfinished code that was + * supposed to be used somewhere? The tests pass without this. + private static class TAPositionBuilder { + private TypeAnnotation.Position pos = new TypeAnnotation.Position(); + + private TAPositionBuilder() { } + + public TypeAnnotation.Position build() { return pos; } + + public static TAPositionBuilder ofType(TypeAnnotation.TargetType type) { + TAPositionBuilder builder = new TAPositionBuilder(); + builder.pos.type = type; + return builder; + } + + public TAPositionBuilder atOffset(int offset) { + switch (pos.type) { + // type cast + case TYPECAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + pos.offset = offset; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atLocalPosition(int offset, int length, int index) { + switch (pos.type) { + // local variable + case LOCAL_VARIABLE: + pos.lvarOffset = new int[] { offset }; + pos.lvarLength = new int[] { length }; + pos.lvarIndex = new int[] { index }; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atParameterIndex(int index) { + switch (pos.type) { + // type parameters + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + // method parameter + case METHOD_FORMAL_PARAMETER: + pos.parameter_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atParamBound(int param, int bound) { + switch (pos.type) { + // type parameters bounds + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + pos.parameter_index = param; + pos.bound_index = bound; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atWildcardPosition(TypeAnnotation.Position pos) { + switch (pos.type) { + // wildcards + case WILDCARD_BOUND: + pos.wildcard_position = pos; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atTypeIndex(int index) { + switch (pos.type) { + // class extends or implements clauses + case CLASS_EXTENDS: + // throws + case THROWS: + pos.type_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atOffsetWithIndex(int offset, int index) { + switch (pos.type) { + // method type argument: wasn't specified + case NEW_TYPE_ARGUMENT: + case METHOD_TYPE_ARGUMENT: + pos.offset = offset; + pos.type_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atGenericLocation(Integer ...loc) { + pos.location = Arrays.asList(loc); + pos.type = pos.type.getGenericComplement(); + return this; + } + }*/ + + /////////////////////// Equality testing ///////////////////// + private static boolean areEquals(int a, int b) { + return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE; + } + + private static boolean areEquals(int[] a, int[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; i annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { + String properName = "L" + name + ";"; + for (TypeAnnotation anno : annotations) { + String actualName = cf.constant_pool.getUTF8Value(anno.annotation.type_index); + if (properName.equals(actualName)) + return anno; + } + return null; + } + + public static boolean compare(Map expectedAnnos, + List actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { + if (actualAnnos.size() != expectedAnnos.size()) { + throw new ComparisionException("Wrong number of annotations", + expectedAnnos, + actualAnnos); + } + + for (Map.Entry e : expectedAnnos.entrySet()) { + String aName = e.getKey(); + TypeAnnotation.Position expected = e.getValue(); + TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); + if (actual == null) + throw new ComparisionException("Expected annotation not found: " + aName); + + // TODO: you currently get an exception if the test case does not use all necessary + // annotation attributes, e.g. forgetting the offset for a local variable. + // It would be nicer to give an understandable warning instead. + if (!areEquals(expected, actual.position)) { + throw new ComparisionException("Unexpected position for annotation : " + aName + + "\n Expected: " + expected.toString() + + "\n Found: " + actual.position.toString()); + } + } + return true; + } +} + +class ComparisionException extends RuntimeException { + private static final long serialVersionUID = -3930499712333815821L; + + public final Map expected; + public final List found; + + public ComparisionException(String message) { + this(message, null, null); + } + + public ComparisionException(String message, Map expected, List found) { + super(message); + this.expected = expected; + this.found = found; + } + + public String toString() { + String str = super.toString(); + if (expected != null && found != null) { + str += "\n\tExpected: " + expected.size() + " annotations; but found: " + found.size() + " annotations\n" + + " Expected: " + expected + + "\n Found: " + found; + } + return str; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for repeating type annotations + * @compile -g Driver.java ReferenceInfoUtil.java RepeatingTypeAnnotations.java + * @run main Driver RepeatingTypeAnnotations + * @author Werner Dietl + */ +public class RepeatingTypeAnnotations { + // Field types + @TADescription(annotation = "RTAs", type = FIELD) + public String fieldAsPrimitive() { + return "@RTA @RTA int test;"; + } + + // Method returns + @TADescription(annotation = "RTAs", type = METHOD_RETURN) + public String methodReturn1() { + return "@RTA @RTA int test() { return 0; }"; + } + + @TADescription(annotation = "RTAs", type = METHOD_RETURN) + public String methodReturn2() { + return "@RTAs({@RTA, @RTA}) int test() { return 0; }"; + } + + // Method parameters + @TADescriptions({ + @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "RTBs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, + genericLocation = { 3, 0 }) + }) + public String methodParam1() { + return "void m(@RTA @RTA List<@RTB @RTB String> p) {}"; + } + + @TADescriptions({ + @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "RTBs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, + genericLocation = { 3, 0 }) + }) + public String methodParam2() { + return "void m(@RTAs({@RTA, @RTA}) List<@RTBs({@RTB, @RTB}) String> p) {}"; + } + + // TODO: test that all other locations work with repeated type annotations. +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for type casts + * @compile -g Driver.java ReferenceInfoUtil.java TypeCasts.java + * @run main Driver TypeCasts + */ +public class TypeCasts { + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return (@TA String)null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = CAST, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectArray() { + return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectGeneric() { + return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnPrim() { + return "Object returnPrim() { return (@TA int)0; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnPrimArray() { + return "Object returnPrimArray() { return (@TB int @TA [])null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = (@TA String)null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectArray() { + return "void initObjectArray() { Object a = (@TB String @TA [])null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectGeneric() { + return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initPrim() { + return "void initPrim() { Object a = (@TA int)0; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initPrimArray() { + return "void initPrimArray() { Object a = (@TB int @TA [])null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (null == (@TA String)null); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectArray() { + return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectGeneric() { + return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + // compiler optimizes away compile time constants casts + public String eqtestPrim() { + return "void eqtestPrim(int a) { if (0 == (@TA int)a); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestPrimArray() { + return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }"; + } + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 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 + * @summary Test population of reference info for class literals + * @compile -g Driver.java ReferenceInfoUtil.java TypeTests.java + * @run main Driver TypeTests + */ +public class TypeTests { + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return null instanceof @TA String; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectArray() { + return "Object returnObjectArray() { return null instanceof @TC String @TA [] @TB []; }"; + } + + // no type test for primitives + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnPrimArray() { + return "Object returnPrimArray() { return null instanceof @TC int @TA [] @TB []; }"; + } + + // no void + // no void array + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = null instanceof @TA String; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectArray() { + return "void initObjectArray() { Object a = null instanceof @TC String @TA [] @TB []; }"; + } + + // no primitive instanceof + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initPrimArray() { + return "void initPrimArray() { Object a = null instanceof @TC int @TA [] @TB []; }"; + } + + // no void + // no void array + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (true == (null instanceof @TA String)); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectArray() { + return "void eqtestObjectArray() { if (true == (null instanceof @TC String @TA [] @TB [])); }"; + } + + // no primitives + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestPrimArray() { + return "void eqtestPrimArray() { if (true == (null instanceof @TC int @TA [] @TB [])); }"; + } + + // no void + // no void array + +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/api/EndPositions.java --- a/langtools/test/tools/javac/api/EndPositions.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/api/EndPositions.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, 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 @@ -28,11 +28,7 @@ * an annotation processor is present */ -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.tree.Tree; import com.sun.source.util.JavacTask; -import com.sun.source.util.Trees; import java.io.IOException; import java.net.URI; import java.util.Arrays; @@ -72,16 +68,17 @@ JavacTask task = (JavacTask)javac.getTask(null, null, diagnostics, options, null, compilationUnits); boolean valid = task.call(); if (valid) - throw new AssertionError("Compilation succeeded unexpectedly"); + throw new AssertionError("Expected one error, but found none."); List> errors = diagnostics.getDiagnostics(); if (errors.size() != 1) - throw new AssertionError("Expected one error only, but found " + errors.size() + " errors"); + throw new AssertionError("Expected one error only, but found " + errors.size() + "; errors: " + errors); Diagnostic error = errors.get(0); if (error.getStartPosition() >= error.getEndPosition()) throw new AssertionError("Expected start to be less than end position: start [" + - error.getStartPosition() + "], end [" + error.getEndPosition() +"]"); + error.getStartPosition() + "], end [" + error.getEndPosition() +"]" + + "; diagnostics code: " + error.getCode()); System.out.println("All is good!"); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/CheckResourceKeys.java --- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, 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 @@ -200,6 +200,7 @@ Set needToInvestigate = new TreeSet(Arrays.asList( + "compiler.misc.fatal.err.cant.close.loader", // Supressed by JSR308 "compiler.err.cant.read.file", // UNUSED "compiler.err.illegal.self.ref", // UNUSED "compiler.err.io.exception", // UNUSED diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples.not-yet.txt --- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jan 23 13:27:24 2013 -0800 @@ -48,6 +48,7 @@ compiler.misc.bad.enclosing.method # bad class file compiler.misc.bad.runtime.invisible.param.annotations # bad class file compiler.misc.bad.signature # bad class file +compiler.misc.bad.type.annotation.value compiler.misc.base.membership # UNUSED compiler.misc.ccf.found.later.version compiler.misc.ccf.unrecognized.attribute diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,41 @@ +/* + * 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.cant.annotate.nested.type + +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + interface Outer { + interface Inner {} + } + + // Error: + @A Outer.Inner f; + + // OK: + @A Outer g; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,41 @@ +/* + * 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.cant.annotate.static.class + +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + static class Outer { + class Inner {} + } + + // Error: + @A Outer.Inner f; + + // OK: + @A Outer g; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,28 @@ +/* + * 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.type + +class IncorrectReceiverType { + void m(Object this) {} +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,31 @@ +/* + * 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.no.annotations.on.dot.class + +class NoAnnotationsOnDotClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + Object o = @A Object.class; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,28 @@ +/* + * 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.this.as.identifier + +class ThisAsIdentifier { + Object this; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,34 @@ +/* + * 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 + * 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.type.annotations.not.supported.in.source +// key: compiler.warn.source.no.bootclasspath +// options: -source 6 + +@interface Anno { } + +class TypeAnnotationsNotSupported { + void m() { + int i = (@Anno int) 3.14; + } +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/failover/CheckAttributedTree.java --- a/langtools/test/tools/javac/failover/CheckAttributedTree.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java Wed Jan 23 13:27:24 2013 -0800 @@ -362,11 +362,18 @@ } Info self = new Info(tree, endPosTable); - check(!mandatoryType(tree) || - (tree.type != null && - checkFields(tree)), - "'null' found in tree ", - self); + if (mandatoryType(tree)) { + check(tree.type != null, + "'null' field 'type' found in tree ", self); + if (tree.type==null) + new Throwable().printStackTrace(); + } + + Field errField = checkFields(tree); + if (errField!=null) { + check(false, + "'null' field '" + errField.getName() + "' found in tree ", self); + } Info prevEncl = encl; encl = self; @@ -395,7 +402,7 @@ } } - boolean checkFields(JCTree t) { + Field checkFields(JCTree t) { List fieldsToCheck = treeUtil.getFieldsOfType(t, excludedFields, Symbol.class, @@ -403,7 +410,7 @@ for (Field f : fieldsToCheck) { try { if (f.get(t) == null) { - return false; + return f; } } catch (IllegalAccessException e) { @@ -411,7 +418,7 @@ //swallow it } } - return true; + return null; } @Override diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out --- a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out Wed Jan 23 13:27:24 2013 -0800 @@ -1,4 +1,3 @@ SemanticErrorTest.java:11:46: compiler.err.repeated.interface - compiler.err.proc.messager: Deliberate Error -SemanticErrorTest.java:11:46: compiler.err.repeated.interface -2 errors +2 errors \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, 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 @@ -78,7 +78,7 @@ @Nesting(LOCAL) class LocalClass{}; - Object o = new /*@Nesting(ANONYMOUS)*/ Object() { // An anonymous annotated class + Object o = new @Nesting(ANONYMOUS) Object() { // An anonymous annotated class public String toString() { return "I have no name!"; } @@ -96,10 +96,9 @@ List names = new ArrayList(); for(Class clazz : classes) { String name = clazz.getName(); - Nesting anno = clazz.getAnnotation(Nesting.class); System.out.format("%s is %s%n", clazz.getName(), - anno == null ? "(unset/ANONYMOUS)" : anno.value()); + clazz.getAnnotation(Nesting.class).value()); testClassName(name); names.add(name); } @@ -158,6 +157,7 @@ } } +@Target({ElementType.TYPE, ElementType.TYPE_USE}) @Retention(RUNTIME) @interface Nesting { NestingKind value(); @@ -185,8 +185,8 @@ typeElt.getQualifiedName().toString(), typeElt.getKind().toString(), nestingKind.toString()); - Nesting anno = typeElt.getAnnotation(Nesting.class); - if ((anno == null ? NestingKind.ANONYMOUS : anno.value()) != nestingKind) { + + if (typeElt.getAnnotation(Nesting.class).value() != nestingKind) { throw new RuntimeException("Mismatch of expected and reported nesting kind."); } } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,7 @@ * @summary Modeling type implementing missing interfaces * @library /tools/javac/lib * @build JavacTestingAbstractProcessor TestMissingElement - * @compile -proc:only -XprintRounds -processor TestMissingElement InvalidSource.java + * @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java */ import java.util.*; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,49 @@ +Round 1: + input files: {ExpectInterfaces, ExpectSupertype, OK, InvalidSource} + annotations: [ExpectSupertype, ExpectInterfaces] + last round: false +Round 2: + input files: {} + annotations: [] + last round: true +InvalidSource.java:55:42: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:58:44: compiler.err.doesnt.exist: A +InvalidSource.java:61:54: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.package, java.util, null) +InvalidSource.java:64:47: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:67:44: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:70:46: compiler.err.doesnt.exist: A +InvalidSource.java:73:55: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:76:59: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:79:46: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:79:49: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:82:44: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:85:46: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:88:50: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:91:45: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:91:48: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:94:49: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:97:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:97:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:100:49: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:103:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:103:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:106:58: compiler.err.cant.resolve.location: kindname.class, X, , , (compiler.misc.location: kindname.class, InvalidSource, null) +22 errors +check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A! +check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B! +check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A! +check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A! +check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B! +check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List \ No newline at end of file diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java --- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 @@ * @author Scott Seligman * @library /tools/javac/lib * @build JavacTestingAbstractProcessor DirectSupersOfErr - * @compile -processor DirectSupersOfErr -proc:only C1.java + * @compile/fail/ref=DirectSupersOfErr.ref -processor DirectSupersOfErr -proc:only -XDrawDiagnostics C1.java */ import java.util.Set; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,2 @@ +C1.java:24:18: compiler.err.cant.resolve: kindname.class, Bogus, , +1 error diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/tree/TreeKindTest.java --- a/langtools/test/tools/javac/tree/TreeKindTest.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/tree/TreeKindTest.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 @@ import com.sun.source.tree.*; -public class TreeKindTest{ +public class TreeKindTest { public static void main(String... args) { boolean ok = true; @@ -108,6 +108,11 @@ ok = ok & verify(k, i, i == ClassTree.class); break; + case ANNOTATION: + case TYPE_ANNOTATION: + ok = ok & verify(k, i, i == AnnotationTree.class); + break; + case OTHER: ok = ok & verify(k, i, i == null); break; diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/tree/TreePosTest.java --- a/langtools/test/tools/javac/tree/TreePosTest.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/tree/TreePosTest.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, 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 @@ -75,6 +75,7 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCAnnotatedType; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -100,7 +101,8 @@ * @test * @bug 6919889 * @summary assorted position errors in compiler syntax trees - * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . + * OLD: -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . + * @run main TreePosTest -q -r . */ public class TreePosTest { /** @@ -367,15 +369,24 @@ // e.g. int[][] a = new int[2][]; check("encl.start <= start", encl, self, encl.start <= self.start); check("start <= pos", encl, self, self.start <= self.pos); - if (!(self.tag == TYPEARRAY + if (!( (self.tag == TYPEARRAY || + isAnnotatedArray(self.tree)) && (encl.tag == VARDEF || encl.tag == METHODDEF || - encl.tag == TYPEARRAY))) { + encl.tag == TYPEARRAY || + isAnnotatedArray(encl.tree)) + || + encl.tag == ANNOTATED_TYPE && self.tag == SELECT + )) { check("encl.pos <= start || end <= encl.pos", encl, self, encl.pos <= self.start || self.end <= encl.pos); } check("pos <= end", encl, self, self.pos <= self.end); - if (!(self.tag == TYPEARRAY && encl.tag == TYPEARRAY)) { + if (!( (self.tag == TYPEARRAY || isAnnotatedArray(self.tree)) && + (encl.tag == TYPEARRAY || isAnnotatedArray(encl.tree)) + || + encl.tag == MODIFIERS && self.tag == ANNOTATION + ) ) { check("end <= encl.end", encl, self, self.end <= encl.end); } } @@ -387,6 +398,11 @@ encl = prevEncl; } + private boolean isAnnotatedArray(JCTree tree) { + return tree.hasTag(ANNOTATED_TYPE) && + ((JCAnnotatedType)tree).underlyingType.hasTag(TYPEARRAY); + } + @Override public void visitVarDef(JCVariableDecl tree) { // enum member declarations are desugared in the parser and have @@ -427,7 +443,8 @@ viewer.addEntry(sourcefile, label, encl, self); } - String s = self.tree.toString(); + String s = "encl: " + encl.tree.toString() + + " this: " + self.tree.toString(); String msg = sourcefile.getName() + ": " + label + ": " + "encl:" + encl + " this:" + self + "\n" + s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " "); diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/treeannotests/AnnoTreeTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/treeannotests/AnnoTreeTests.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,44 @@ +/* + * 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 + * 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 + * @build DA TA Test TestProcessor + * @compile -proc:only -processor TestProcessor AnnoTreeTests.java + */ + +@Test(4) +class AnnoTreeTests { + // primitive types + // @TA("int") int i1 = 0; // TODO: Only visible via ClassFile + long i2 = (@TA("long") long) 0; + + // simple array types + // @DA("short") short[] a1; // TODO: Only visible via ClassFile + byte @TA("byte[]") [] a2; + float[] a3 = (@TA("float") float[]) null; + double[] a4 = (double @TA("double[]") []) null; + + // multi-dimensional array types + // (still to come) +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/treeannotests/TestProcessor.java --- a/langtools/test/tools/javac/treeannotests/TestProcessor.java Wed Jan 23 20:57:40 2013 +0000 +++ b/langtools/test/tools/javac/treeannotests/TestProcessor.java Wed Jan 23 13:27:24 2013 -0800 @@ -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 @@ -203,13 +203,16 @@ * expression name=value. */ String getStringValue(JCExpression e) { - if (e.getTag() == JCTree.ASSIGN) { + if (e.hasTag(JCTree.Tag.ASSIGN)) { JCAssign a = (JCAssign) e; JCExpression rhs = a.rhs; - if (rhs.getTag() == JCTree.LITERAL) { + if (rhs.hasTag(JCTree.Tag.LITERAL)) { JCLiteral l = (JCLiteral) rhs; return (String) l.value; } + } else if (e.hasTag(JCTree.Tag.LITERAL)) { + JCLiteral l = (JCLiteral) e; + return (String) l.value; } throw new IllegalArgumentException(e.toString()); } diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java --- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java Wed Jan 23 20:57:40 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ - -/* - * Copyright (c) 2008, 2010, 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 6843077 - * @summary random tests for new locations - * @author Matt Papi - * @compile/fail/ref=BasicTest.out -XDrawDiagnostics BasicTest.java - */ - -import java.util.*; -import java.io.*; - -@interface A {} -@interface B {} -@interface C {} -@interface D {} - -//308: Test inverted to verify that type annotations can not be parsed yet. - -/** - * Tests basic JSR 308 parser functionality. We don't really care about what - * the parse tree looks like, just that these annotations can be parsed. - */ -class BasicTest extends @B LinkedList implements @C List { - - void test() { - - // Handle annotated class literals/cast types - Class c = @A String.class; - Object o = (@A Object) "foo"; - - // Handle annotated "new" expressions (except arrays; see ArrayTest) - String s = new @A String("bar"); - - boolean b = o instanceof @A Object; - - - @A Map<@B List<@C String>, @D String> map = - new @A HashMap<@B List<@C String>, @D String>(); - - Class c2 = @A String.class; - } - - // Handle receiver annotations - // Handle annotations on a qualified identifier list - void test2() @C @D throws @A IllegalArgumentException, @B IOException { - - } - - // Handle annotations on a varargs element type - void test3(Object @A... objs) { - - } -} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out --- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out Wed Jan 23 20:57:40 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -BasicTest.java:47:27: compiler.err.illegal.start.of.type -BasicTest.java:47:28: compiler.err.expected: '{' -BasicTest.java:47:36: compiler.err.expected: token.identifier -BasicTest.java:47:38: compiler.err.illegal.start.of.type -BasicTest.java:47:45: compiler.err.expected: token.identifier -BasicTest.java:47:47: compiler.err.expected: ';' -BasicTest.java:47:62: compiler.err.expected: token.identifier -BasicTest.java:47:84: compiler.err.expected: token.identifier -BasicTest.java:52:22: compiler.err.illegal.start.of.expr -BasicTest.java:52:31: compiler.err.expected: ';' -BasicTest.java:52:37: compiler.err.expected: token.identifier -BasicTest.java:53:30: compiler.err.expected: token.identifier -BasicTest.java:53:31: compiler.err.expected: -> -BasicTest.java:56:23: compiler.err.expected: token.identifier -BasicTest.java:56:24: compiler.err.expected2: '(', '[' -BasicTest.java:56:25: compiler.err.expected: ';' -BasicTest.java:56:27: compiler.err.invalid.meth.decl.ret.type.req -BasicTest.java:56:34: compiler.err.illegal.start.of.type -BasicTest.java:58:34: compiler.err.illegal.start.of.type -BasicTest.java:61:16: compiler.err.illegal.start.of.type -BasicTest.java:61:18: compiler.err.expected: ';' -BasicTest.java:61:24: compiler.err.illegal.start.of.type -BasicTest.java:61:26: compiler.err.expected: ';' -BasicTest.java:61:33: compiler.err.expected: token.identifier -BasicTest.java:61:34: compiler.err.illegal.start.of.type -BasicTest.java:61:35: compiler.err.expected: token.identifier -BasicTest.java:61:37: compiler.err.expected: ';' -BasicTest.java:61:45: compiler.err.expected: token.identifier -BasicTest.java:61:50: compiler.err.expected: token.identifier -BasicTest.java:62:16: compiler.err.expected: token.identifier -BasicTest.java:62:17: compiler.err.expected2: '(', '[' -BasicTest.java:62:18: compiler.err.expected: ';' -BasicTest.java:62:28: compiler.err.illegal.start.of.type -BasicTest.java:62:30: compiler.err.expected: ';' -BasicTest.java:62:36: compiler.err.illegal.start.of.type -BasicTest.java:62:38: compiler.err.expected: ';' -BasicTest.java:62:45: compiler.err.expected: token.identifier -BasicTest.java:62:46: compiler.err.illegal.start.of.type -BasicTest.java:62:47: compiler.err.expected: token.identifier -BasicTest.java:62:49: compiler.err.expected: ';' -BasicTest.java:62:57: compiler.err.expected: token.identifier -BasicTest.java:62:58: compiler.err.illegal.start.of.type -BasicTest.java:62:59: compiler.err.expected: token.identifier -BasicTest.java:64:25: compiler.err.illegal.start.of.type -BasicTest.java:64:27: compiler.err.expected: ';' -BasicTest.java:64:34: compiler.err.expected: token.identifier -BasicTest.java:64:38: compiler.err.expected: token.identifier -BasicTest.java:64:41: compiler.err.illegal.start.of.expr -BasicTest.java:64:50: compiler.err.expected: ';' -BasicTest.java:64:56: compiler.err.expected: token.identifier -BasicTest.java:69:17: compiler.err.expected: ';' -BasicTest.java:69:24: compiler.err.illegal.start.of.type -BasicTest.java:69:30: compiler.err.expected: ';' -BasicTest.java:69:59: compiler.err.expected: token.identifier -BasicTest.java:69:74: compiler.err.expected: ';' -BasicTest.java:74:22: compiler.err.expected: token.identifier -BasicTest.java:74:24: compiler.err.expected: ';' -BasicTest.java:74:25: compiler.err.illegal.start.of.type -BasicTest.java:74:33: compiler.err.expected: ';' -BasicTest.java:77:2: compiler.err.premature.eof -60 errors diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2008, 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.io.*; +import com.sun.tools.classfile.*; + +/* + * @test JSR175Annotations + * @bug 6843077 + * @summary test that only type annotations are recorded as such in classfile + */ + +public class JSR175Annotations { + public static void main(String[] args) throws Exception { + new JSR175Annotations().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + 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, 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; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.*;"); + out.println("abstract class Test { "); + out.println(" @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})"); + out.println(" @Retention(RetentionPolicy.RUNTIME)"); + out.println(" @interface A { }"); + out.println(" @A String m;"); + out.println(" @A String method(@A String a) {"); + out.println(" return a;"); + out.println(" }"); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 0; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/NewArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/NewArray.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2008, 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.io.*; +import com.sun.tools.classfile.*; + +/* + * @test NewArray + * @bug 6843077 + * @summary test that all type annotations are present in the classfile + */ + +public class NewArray { + public static void main(String[] args) throws Exception { + new NewArray().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + 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); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + 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; + } + } + + // 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 { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + 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("}"); + + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 9; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/Presence.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/Presence.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2008, 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.io.*; +import java.lang.annotation.ElementType; + +import com.sun.tools.classfile.*; + +/* + * @test Presence + * @bug 6843077 + * @summary test that all type annotations are present in the classfile + */ + +public class Presence { + public static void main(String[] args) throws Exception { + new Presence().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + 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); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + 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; + } + } + + // 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 { + File f = new File("Test.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(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println(" @interface A { }"); + + out.println(" Map<@A String, Map<@A String, @A String>> f1;"); + + out.println(" <@A TM extends @A List<@A String>>"); + out.println(" Map<@A String, @A List<@A String>>"); + out.println(" method(@A Test 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;"); + out.println(" @A String @A [] [] @A[] lc3 = null;"); + out.println(" List> lc4 = null;"); + out.println(" Object lc5 = (@A List<@A String>) null;"); + out.println(" boolean lc6 = lc1 instanceof @A String;"); + out.println(" boolean lc7 = lc5 instanceof @A String @A [] @A [];"); + out.println(" new @A ArrayList<@A String>();"); + out.println(" Object lc8 = new @A String @A [4];"); + out.println(" try {"); + out.println(" Object lc10 = int.class;"); + out.println(" } catch (@A Exception e) { e.toString(); }"); + out.println(" return null;"); + out.println(" }"); + out.println(" void vararg1(String @A ... t) { } "); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 38; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/PresenceInner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/PresenceInner.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,187 @@ +/* + * 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test PresenceInner + * @bug 6843077 + * @summary test that annotations in inner types count only once + */ + +public class PresenceInner { + public static void main(String[] args) throws Exception { + new PresenceInner().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + 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); + } + + // counts are zero when vising outer class + countAnnotations(0); + + // visit inner class + File innerFile = new File("Test$1Inner.class"); + ClassFile icf = ClassFile.read(innerFile); + test(icf); + for (Field f : icf.fields) { + test(cf, f); + } + for (Method m: icf.methods) { + test(cf, m); + } + + countAnnotations(1); + if (errors > 0) + throw new Exception(errors + " errors found"); + 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; + } + } + + // 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 { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + + out.println("import java.lang.annotation.*;"); + out.println("class Test {"); + out.println(" void method() {"); + out.println(" class Inner { }"); + out.println(" }"); + out.println("}"); + out.println("@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println("@interface A { }"); + out.close(); + System.out.println(f.getAbsolutePath()); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations(int expected_invisibles) { + int expected_visibles = 0; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/T6855990.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/T6855990.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,51 @@ +/* + * 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. + */ + +import java.io.*; + +/* + * @test + * @bug 6855990 + * @summary InstructionDetailWriter should support new 308 annotations attribute + */ + +public class T6855990 { + public static void main(String[] args) throws Exception { + new T6855990().run(); + } + + public void run() throws Exception { + @Simple String[] args = { "-c", "-XDdetails:typeAnnotations", "T6855990" }; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + if (out.indexOf("@Simple: LOCAL_VARIABLE") == -1) + throw new Exception("expected output not found"); + } +} + +@interface Simple { } + diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/TypeCasts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,191 @@ +/* + * 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6843077 + * @summary test that typecasts annotation are emitted if only the cast + * expression is optimized away + */ + +public class TypeCasts { + public static void main(String[] args) throws Exception { + new TypeCasts().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + 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); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + 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; + } + } + + // 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 { + File f = new File("Test.java"); + 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(" void emit() {"); + out.println(" Object o = null;"); + out.println(" String s = null;"); + + out.println(" String a0 = (@A String)o;"); + out.println(" Object a1 = (@A Object)o;"); + + out.println(" String b0 = (@A String)s;"); + out.println(" Object b1 = (@A Object)s;"); + out.println(" }"); + + out.println(" void alldeadcode() {"); + out.println(" Object o = null;"); + + out.println(" if (false) {"); + out.println(" String a0 = (@A String)o;"); + out.println(" }"); + out.println(" }"); + + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 4; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/Visibility.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/Visibility.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2008, 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.io.*; +import com.sun.tools.classfile.*; + +/* + * @test Visibility + * @bug 6843077 + * @summary test that type annotations are recorded in the classfile + */ + +public class Visibility { + public static void main(String[] args) throws Exception { + new Visibility().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf, Method 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, 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; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.ElementType;"); + out.println("import java.lang.annotation.Retention;"); + out.println("import java.lang.annotation.RetentionPolicy;"); + out.println("import java.lang.annotation.Target;"); + out.println("abstract class Test { "); + // visible annotations: RUNTIME + out.println(" @Retention(RetentionPolicy.RUNTIME)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface A { }"); + out.println(" void visible(@A Test this) { }"); + + // invisible annotations: CLASS + out.println(" @Retention(RetentionPolicy.CLASS)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface B { }"); + out.println(" void invisible(@B Test this) { }"); + + // source annotations + out.println(" @Retention(RetentionPolicy.SOURCE)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface C { }"); + out.println(" void source(@C Test this) { }"); + + // default visibility: CLASS + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface D { }"); + out.println(" void def(@D Test this) { }"); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_all = 3, expected_visibles = 1, expected_invisibles = 2; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff -r 5a8d00abf076 -r ee1eebe7e210 langtools/test/tools/javap/typeAnnotations/Wildcards.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/typeAnnotations/Wildcards.java Wed Jan 23 13:27:24 2013 -0800 @@ -0,0 +1,177 @@ +/* + * 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test Wildcards + * @bug 6843077 + * @summary test that annotations target wildcards get emitted to classfile + */ +public class Wildcards { + public static void main(String[] args) throws Exception { + new Wildcards().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + 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); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + 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; + } + } + + // 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 { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + 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(" List f;"); + + out.println(" List test(List p) {"); + out.println(" List l;"); // not counted... gets optimized away + out.println(" return null;"); + out.println(" }"); + out.println("}"); + + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 3; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +}