--- a/langtools/make/build.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/make/build.properties Sat Jan 26 19:24:46 2013 -0800
@@ -29,18 +29,18 @@
# Override this path as needed, either on the command line or in
# one of the standard user build.properties files (see build.xml)
-# boot.java.home = /opt/jdk/1.6.0
+# boot.java.home = /opt/jdk/1.7.0
boot.java = ${boot.java.home}/bin/java
boot.javac = ${boot.java.home}/bin/javac
-boot.javac.source = 6
-boot.javac.target = 6
+boot.javac.source = 7
+boot.javac.target = 7
# This is the JDK used to run the product version of the tools,
# for example, for testing. If you're building a complete JDK, specify that.
# Override this path as needed, either on the command line or in
# one of the standard user build.properties files (see build.xml)
-# target.java.home = /opt/jdk/1.7.0
+# target.java.home = /opt/jdk/1.8.0
target.java = ${target.java.home}/bin/java
# Version info -- override as needed
@@ -161,6 +161,14 @@
#
+sjavac.includes = \
+ com/sun/tools/sjavac/
+
+sjavac.tests = \
+ tools/sjavac
+
+#
+
# The following files require the latest JDK to be available.
# The API can be provided by using a suitable boot.java.home
# or by setting import.jdk
--- a/langtools/make/build.xml Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/make/build.xml Sat Jan 26 19:24:46 2013 -0800
@@ -241,15 +241,15 @@
</target>
<target name="build-bootstrap-tools"
- depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"
+ depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah,build-bootstrap-sjavac"
/>
<target name="build-all-tools"
- depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap"
+ depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-sjavac"
/>
<target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
- <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes}"/>
+ <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes} ${sjavac.includes}"/>
</target>
<!-- clean -->
@@ -656,6 +656,40 @@
<target name="javap" depends="build-javap,jtreg-javap,findbugs-javap"/>
+ <!--
+ **** sjavac targets.
+ -->
+
+ <target name="build-bootstrap-sjavac"
+ depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+ <build-bootstrap-classes includes="${sjavac.includes}"/>
+ <build-bootstrap-jar name="sjavac" includes="${sjavac.includes}"
+ jarmainclass="com.sun.tools.sjavac.Main"/>
+ <build-bootstrap-tool name="sjavac"/>
+ </target>
+
+ <target name="build-classes-sjavac" depends="build-classes-javac">
+ <build-classes includes="${sjavac.includes}"/>
+ </target>
+
+ <target name="build-sjavac" depends="build-classes-sjavac">
+ <build-jar name="sjavac" includes="${sjavac.includes}"
+ jarmainclass="com.sun.tools.sjavac.Main"
+ jarclasspath="sjavac.jar"/>
+ <build-tool name="sjavac"/>
+ </target>
+
+ <!-- (no javadoc for javap) -->
+
+ <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
+ <jtreg-tool name="sjavac" tests="${sjavac.tests}"/>
+ </target>
+
+ <target name="findbugs-sjavac" depends="build-sjavac,-def-findbugs">
+ <findbugs-tool name="sjavac"/>
+ </target>
+
+ <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
<!--
**** Create import JDK stubs.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/javadoc/AnnotatedType.java Sat Jan 26 19:24:46 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:
+ * <pre>
+ * {@code @NonNull String}
+ * {@code @Positive int}
+ * </pre>
+ *
+ * @author Mahmood Ali
+ * @since 1.8
+ */
+public interface AnnotatedType extends Type {
+
+ AnnotationDesc[] annotations();
+
+ Type underlyingType();
+}
--- a/langtools/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java Sat Jan 26 19:24:46 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 <code>@exception</code>
--- a/langtools/src/share/classes/com/sun/javadoc/Type.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/javadoc/Type.java Sat Jan 26 19:24:46 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 <code>AnnotatedType</code> if it represents
+ * an annotated type.
+ *
+ * @return a <code>AnnotatedType</code> if the type if an annotated type,
+ * or null if it is not
+ * @since 1.8
+ */
+ AnnotatedType asAnnotatedType();
+
+ /**
* Return this type as an <code>AnnotationTypeDoc</code> if it represents
* an annotation type. Array dimensions are ignored.
*
--- a/langtools/src/share/classes/com/sun/javadoc/TypeVariable.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/javadoc/TypeVariable.java Sat Jan 26 19:24:46 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();
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/AnnotatedTypeTree.java Sat Jan 26 19:24:46 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:
+ * <pre>
+ * {@code @}<em>annotationType String</em>
+ * {@code @}<em>annotationType</em> ( <em>arguments</em> ) <em>Date</em>
+ * </pre>
+ *
+ * @see "JSR 308: Annotations on Java Types"
+ *
+ * @author Mahmood Ali
+ * @since 1.8
+ */
+public interface AnnotatedTypeTree extends ExpressionTree {
+ List<? extends AnnotationTree> getAnnotations();
+ ExpressionTree getUnderlyingType();
+}
--- a/langtools/src/share/classes/com/sun/source/tree/MethodTree.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/MethodTree.java Sat Jan 26 19:24:46 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<? extends TypeParameterTree> getTypeParameters();
List<? extends VariableTree> getParameters();
+ VariableTree getReceiverParameter();
List<? extends ExpressionTree> getThrows();
BlockTree getBody();
Tree getDefaultValue(); // for annotation types
--- a/langtools/src/share/classes/com/sun/source/tree/Tree.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java Sat Jan 26 19:24:46 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),
--- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Sat Jan 26 19:24:46 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,P> {
+ R visitAnnotatedType(AnnotatedTypeTree node, P p);
R visitAnnotation(AnnotationTree node, P p);
R visitMethodInvocation(MethodInvocationTree node, P p);
R visitAssert(AssertTree node, P p);
--- a/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java Sat Jan 26 19:24:46 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<? extends Tree> getBounds();
+ List<? extends AnnotationTree> getAnnotations();
}
--- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Sat Jan 26 19:24:46 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);
}
--- a/langtools/src/share/classes/com/sun/source/util/TaskEvent.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/TaskEvent.java Sat Jan 26 19:24:46 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,
/**
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Sat Jan 26 19:24:46 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;
}
--- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Sat Jan 26 19:24:46 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);
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java Sat Jan 26 19:24:46 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);
+ }
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java Sat Jan 26 19:24:46 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class 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, P> R accept(Visitor<R, P> visitor, P p) {
+ return visitor.visitRuntimeInvisibleTypeAnnotations(this, p);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java Sat Jan 26 19:24:46 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java Sat Jan 26 19:24:46 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class 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, P> R accept(Visitor<R, P> visitor, P p) {
+ return visitor.visitRuntimeVisibleTypeAnnotations(this, p);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java Sat Jan 26 19:24:46 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class 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<Integer> loc = new ArrayList<Integer>(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<TypePathEntry> location = new ArrayList<TypePathEntry>(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<TypePathEntry> getTypePathFromBinary(List<Integer> list) {
+ List<TypePathEntry> loc = new ArrayList<TypePathEntry>(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<Integer> getBinaryFromTypePath(List<TypePathEntry> locs) {
+ List<Integer> loc = new ArrayList<Integer>(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];
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Sat Jan 26 19:24:46 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.
*
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Sat Jan 26 19:24:46 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
@@ -33,8 +33,10 @@
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.RootDocImpl;
/**
* Configure the output based on the command line options.
@@ -172,6 +174,11 @@
public boolean createoverview = false;
/**
+ * Collected set of doclint options
+ */
+ public Set<String> doclintOpts = new LinkedHashSet<String>();
+
+ /**
* Unique Resource Handler for this package.
*/
public final MessageRetriever standardmessage;
@@ -255,6 +262,10 @@
nooverview = true;
} else if (opt.equals("-overview")) {
overview = true;
+ } else if (opt.equals("-xdoclint")) {
+ doclintOpts.add(null);
+ } else if (opt.startsWith("-xdoclint:")) {
+ doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
}
}
if (root.specifiedClasses().length > 0) {
@@ -270,6 +281,10 @@
}
setCreateOverview();
setTopFile(root);
+
+ if (root instanceof RootDocImpl) {
+ ((RootDocImpl) root).initDocLint(doclintOpts);
+ }
}
/**
@@ -303,7 +318,9 @@
option.equals("-serialwarn") ||
option.equals("-use") ||
option.equals("-nonavbar") ||
- option.equals("-nooverview")) {
+ option.equals("-nooverview") ||
+ option.equals("-xdoclint") ||
+ option.startsWith("-xdoclint:")) {
return 1;
} else if (option.equals("-help")) {
System.out.println(getText("doclet.usage"));
@@ -410,6 +427,16 @@
return false;
}
noindex = true;
+ } else if (opt.startsWith("-xdoclint:")) {
+ if (opt.contains("/")) {
+ reporter.printError(getText("doclet.Option_doclint_no_qualifiers"));
+ return false;
+ }
+ if (!DocLint.isValidOption(
+ opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) {
+ reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
+ return false;
+ }
}
}
return true;
@@ -506,8 +533,8 @@
*/
@Override
public Locale getLocale() {
- if (root instanceof com.sun.tools.javadoc.RootDocImpl)
- return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale();
+ if (root instanceof RootDocImpl)
+ return ((RootDocImpl)root).getLocale();
else
return Locale.getDefault();
}
@@ -518,8 +545,8 @@
@Override
public JavaFileManager getFileManager() {
if (fileManager == null) {
- if (root instanceof com.sun.tools.javadoc.RootDocImpl)
- fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager();
+ if (root instanceof RootDocImpl)
+ fileManager = ((RootDocImpl) root).getFileManager();
else
fileManager = new JavacFileManager(new Context(), false, null);
}
@@ -527,4 +554,12 @@
}
private JavaFileManager fileManager;
+
+ @Override
+ public boolean showMessage(SourcePosition pos, String key) {
+ if (root instanceof RootDocImpl) {
+ return pos == null || ((RootDocImpl) root).showTagMessages();
+ }
+ return true;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Sat Jan 26 19:24:46 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;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Sat Jan 26 19:24:46 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<String> 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<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
+ boolean isJava5DeclarationLocation) {
List<String> results = new ArrayList<String>();
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,
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Sat Jan 26 19:24:46 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<String> 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.
*
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Sat Jan 26 19:24:46 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;
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Sat Jan 26 19:24:46 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;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Sat Jan 26 19:24:46 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
@@ -781,4 +781,6 @@
sourcetab = n;
tabSpaces = String.format("%" + n + "s", "");
}
+
+ public abstract boolean showMessage(SourcePosition pos, String key);
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Sat Jan 26 19:24:46 2013 -0800
@@ -11,6 +11,8 @@
doclet.Class_0_extends_implements_serializable=Class {0} extends {1} implements Serializable
doclet.Option_conflict=Option {0} conflicts with {1}
doclet.Option_reuse=Option reused: {0}
+doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments
+doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option
doclet.exception_encountered= {0} encountered \n\
\twhile attempting to create file: {1}
doclet.perform_copy_exception_encountered= {0} encountered while \n\
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java Sat Jan 26 19:24:46 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
@@ -60,9 +60,9 @@
private ResourceBundle messageRB;
/**
- * Initilize the ResourceBundle with the given resource.
+ * Initialize the ResourceBundle with the given resource.
*
- * @param rb the esource bundle to read.
+ * @param rb the resource bundle to read.
*/
public MessageRetriever(ResourceBundle rb) {
this.configuration = null;
@@ -71,7 +71,7 @@
}
/**
- * Initilize the ResourceBundle with the given resource.
+ * Initialize the ResourceBundle with the given resource.
*
* @param configuration the configuration
* @param resourcelocation Resource.
@@ -189,7 +189,8 @@
* @param args arguments to be replaced in the message.
*/
public void warning(SourcePosition pos, String key, Object... args) {
- printWarning(pos, getText(key, args));
+ if (configuration.showMessage(pos, key))
+ printWarning(pos, getText(key, args));
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Sat Jan 26 19:24:46 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<Type> resultsList = new ArrayList<Type>(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<Type> 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());
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java Sat Jan 26 19:24:46 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.
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java Sat Jan 26 19:24:46 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;
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Sat Jan 26 19:24:46 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
@@ -25,6 +25,7 @@
package com.sun.tools.doclint;
+import com.sun.source.doctree.LiteralTree;
import java.util.regex.Matcher;
import com.sun.source.doctree.LinkTree;
import java.net.URI;
@@ -91,10 +92,11 @@
boolean foundInheritDoc = false;
boolean foundReturn = false;
- enum Flag {
+ public enum Flag {
TABLE_HAS_CAPTION,
HAS_ELEMENT,
- HAS_TEXT
+ HAS_TEXT,
+ REPORTED_BAD_INLINE
}
static class TagStackItem {
@@ -194,7 +196,8 @@
@Override
public Void visitText(TextTree tree, Void ignore) {
- if (!tree.getBody().trim().isEmpty()) {
+ if (hasNonWhitespace(tree)) {
+ checkAllowsText(tree);
markEnclosingTag(Flag.HAS_TEXT);
}
return null;
@@ -202,6 +205,7 @@
@Override
public Void visitEntity(EntityTree tree, Void ignore) {
+ checkAllowsText(tree);
markEnclosingTag(Flag.HAS_TEXT);
String name = tree.getName().toString();
if (name.startsWith("#")) {
@@ -217,6 +221,18 @@
return null;
}
+ void checkAllowsText(DocTree tree) {
+ TagStackItem top = tagStack.peek();
+ if (top != null
+ && top.tree.getKind() == DocTree.Kind.START_ELEMENT
+ && !top.tag.acceptsText()) {
+ if (top.flags.add(Flag.REPORTED_BAD_INLINE)) {
+ env.messages.error(HTML, tree, "dc.text.not.allowed",
+ ((StartElementTree) top.tree).getName());
+ }
+ }
+ }
+
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="HTML elements">
@@ -229,53 +245,22 @@
if (t == null) {
env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
} else {
+ for (TagStackItem tsi: tagStack) {
+ if (tsi.tag.accepts(t)) {
+ while (tagStack.peek() != tsi) tagStack.pop();
+ break;
+ } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL)
+ break;
+ }
+
+ checkStructure(tree, t);
+
// tag specific checks
switch (t) {
// check for out of sequence headers, such as <h1>...</h1> <h3>...</h3>
case H1: case H2: case H3: case H4: case H5: case H6:
checkHeader(tree, t);
break;
- // <p> inside <pre>
- case P:
- TagStackItem top = tagStack.peek();
- if (top != null && top.tag == HtmlTag.PRE)
- env.messages.warning(HTML, tree, "dc.tag.p.in.pre");
- break;
- }
-
- // check that only block tags and inline tags are used,
- // and that blocks tags are not used within inline tags
- switch (t.blockType) {
- case INLINE:
- break;
- case BLOCK:
- TagStackItem top = tagStack.peek();
- if (top != null && top.tag != null && top.tag.blockType == HtmlTag.BlockType.INLINE) {
- switch (top.tree.getKind()) {
- case START_ELEMENT: {
- Name name = ((StartElementTree) top.tree).getName();
- env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
- treeName, name);
- break;
- }
- case LINK:
- case LINK_PLAIN: {
- String name = top.tree.getKind().tagName;
- env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
- treeName, name);
- break;
- }
- default:
- env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.other",
- treeName);
- }
- }
- break;
- case OTHER:
- env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
- break;
- default:
- throw new AssertionError();
}
if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
@@ -323,6 +308,58 @@
}
}
+ private void checkStructure(StartElementTree tree, HtmlTag t) {
+ Name treeName = tree.getName();
+ TagStackItem top = tagStack.peek();
+ switch (t.blockType) {
+ case BLOCK:
+ if (top == null || top.tag.accepts(t))
+ return;
+
+ switch (top.tree.getKind()) {
+ case START_ELEMENT: {
+ if (top.tag.blockType == HtmlTag.BlockType.INLINE) {
+ Name name = ((StartElementTree) top.tree).getName();
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
+ treeName, name);
+ return;
+ }
+ }
+ break;
+
+ case LINK:
+ case LINK_PLAIN: {
+ String name = top.tree.getKind().tagName;
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
+ treeName, name);
+ return;
+ }
+ }
+ break;
+
+ case INLINE:
+ if (top == null || top.tag.accepts(t))
+ return;
+ break;
+
+ case LIST_ITEM:
+ case TABLE_ITEM:
+ if (top != null) {
+ // reset this flag so subsequent bad inline content gets reported
+ top.flags.remove(Flag.REPORTED_BAD_INLINE);
+ if (top.tag.accepts(t))
+ return;
+ }
+ break;
+
+ case OTHER:
+ env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+ return;
+ }
+
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName);
+ }
+
private void checkHeader(StartElementTree tree, HtmlTag tag) {
// verify the new tag
if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) {
@@ -359,9 +396,8 @@
env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
} else if (t.endKind == HtmlTag.EndKind.NONE) {
env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName);
- } else if (tagStack.isEmpty()) {
- env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
} else {
+ boolean done = false;
while (!tagStack.isEmpty()) {
TagStackItem top = tagStack.peek();
if (t == top.tag) {
@@ -378,11 +414,8 @@
&& !top.flags.contains(Flag.HAS_ELEMENT)) {
env.messages.warning(HTML, tree, "dc.tag.empty", treeName);
}
- if (t.flags.contains(HtmlTag.Flag.NO_TEXT)
- && top.flags.contains(Flag.HAS_TEXT)) {
- env.messages.error(HTML, tree, "dc.text.not.allowed", treeName);
- }
tagStack.pop();
+ done = true;
break;
} else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
tagStack.pop();
@@ -400,10 +433,15 @@
tagStack.pop();
} else {
env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+ done = true;
break;
}
}
}
+
+ if (!done && tagStack.isEmpty()) {
+ env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+ }
}
return super.visitEndElement(tree, ignore);
@@ -447,14 +485,18 @@
if (currTag != HtmlTag.A) {
break;
}
- // fallthrough
+ // fallthrough
case ID:
String value = getAttrValue(tree);
- if (!validName.matcher(value).matches()) {
- env.messages.error(HTML, tree, "dc.invalid.anchor", value);
- }
- if (!foundAnchors.add(value)) {
- env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+ if (value == null) {
+ env.messages.error(HTML, tree, "dc.anchor.value.missing");
+ } else {
+ if (!validName.matcher(value).matches()) {
+ env.messages.error(HTML, tree, "dc.invalid.anchor", value);
+ }
+ if (!foundAnchors.add(value)) {
+ env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+ }
}
break;
@@ -542,6 +584,19 @@
}
@Override
+ public Void visitLiteral(LiteralTree tree, Void ignore) {
+ if (tree.getKind() == DocTree.Kind.CODE) {
+ for (TagStackItem tsi: tagStack) {
+ if (tsi.tag == HtmlTag.CODE) {
+ env.messages.warning(HTML, tree, "dc.tag.code.within.code");
+ break;
+ }
+ }
+ }
+ return super.visitLiteral(tree, ignore);
+ }
+
+ @Override
public Void visitParam(ParamTree tree, Void ignore) {
boolean typaram = tree.isTypeParameter();
IdentifierTree nameTree = tree.getName();
@@ -740,7 +795,7 @@
for (DocTree d: list) {
switch (d.getKind()) {
case TEXT:
- if (!((TextTree) d).getBody().trim().isEmpty())
+ if (hasNonWhitespace((TextTree) d))
return;
break;
default:
@@ -749,6 +804,16 @@
}
env.messages.warning(SYNTAX, tree, "dc.empty", tree.getKind().tagName);
}
+
+ boolean hasNonWhitespace(TextTree tree) {
+ String s = tree.getBody();
+ for (int i = 0; i < s.length(); i++) {
+ if (!Character.isWhitespace(s.charAt(i)))
+ return true;
+ }
+ return false;
+ }
+
// </editor-fold>
}
--- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Sat Jan 26 19:24:46 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
@@ -122,7 +122,7 @@
if (javacFiles.isEmpty()) {
if (!needHelp)
- System.out.println("no files given");
+ out.println("no files given");
}
JavacTool tool = JavacTool.create();
@@ -179,11 +179,11 @@
}
} else if (arg.equals(STATS)) {
env.messages.setStatsEnabled(true);
- } else if (arg.matches("-bootclasspath") && i + 1 < args.length) {
+ } else if (arg.equals("-bootclasspath") && i + 1 < args.length) {
javacBootClassPath = splitPath(args[++i]);
- } else if (arg.matches("-classpath") && i + 1 < args.length) {
+ } else if (arg.equals("-classpath") && i + 1 < args.length) {
javacClassPath = splitPath(args[++i]);
- } else if (arg.matches("-sourcepath") && i + 1 < args.length) {
+ } else if (arg.equals("-sourcepath") && i + 1 < args.length) {
javacSourcePath = splitPath(args[++i]);
} else if (arg.equals(XMSGS_OPTION)) {
env.messages.setOptions(null);
@@ -234,6 +234,8 @@
out.println(" equivalent to -Xmsgs:all/protected, meaning that");
out.println(" all messages are reported for protected and public");
out.println(" declarations only. ");
+ out.println(" -stats");
+ out.println(" Report statistics on the reported issues.");
out.println(" -h -help --help -usage -?");
out.println(" Show this message.");
out.println("");
@@ -247,7 +249,7 @@
List<File> splitPath(String path) {
List<File> files = new ArrayList<File>();
- for (String f: path.split(File.separator)) {
+ for (String f: path.split(File.pathSeparator)) {
if (f.length() > 0)
files.add(new File(f));
}
--- a/langtools/src/share/classes/com/sun/tools/doclint/Entity.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Entity.java Sat Jan 26 19:24:46 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
@@ -43,7 +43,7 @@
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
-enum Entity {
+public enum Entity {
nbsp(160),
iexcl(161),
cent(162),
--- a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java Sat Jan 26 19:24:46 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
@@ -57,16 +57,22 @@
B(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
- BLOCKQUOTE,
+ BIG(BlockType.INLINE, EndKind.REQUIRED,
+ EnumSet.of(Flag.EXPECT_CONTENT)),
+
+ BLOCKQUOTE(BlockType.BLOCK, EndKind.REQUIRED,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
BODY(BlockType.OTHER, EndKind.REQUIRED),
BR(BlockType.INLINE, EndKind.NONE,
attrs(AttrKind.USE_CSS, CLEAR)),
- CAPTION(EnumSet.of(Flag.EXPECT_CONTENT)),
+ CAPTION(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+ EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
- CENTER,
+ CENTER(BlockType.BLOCK, EndKind.REQUIRED,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
CITE(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
@@ -74,17 +80,23 @@
CODE(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
- DD(BlockType.BLOCK, EndKind.OPTIONAL,
- EnumSet.of(Flag.EXPECT_CONTENT)),
+ DD(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
- DIV,
+ DIV(BlockType.BLOCK, EndKind.REQUIRED,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
DL(BlockType.BLOCK, EndKind.REQUIRED,
- EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
- attrs(AttrKind.USE_CSS, COMPACT)),
+ EnumSet.of(Flag.EXPECT_CONTENT),
+ attrs(AttrKind.USE_CSS, COMPACT)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == DT) || (t == DD);
+ }
+ },
- DT(BlockType.BLOCK, EndKind.OPTIONAL,
- EnumSet.of(Flag.EXPECT_CONTENT)),
+ DT(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+ EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
EM(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.NO_NEST)),
@@ -97,12 +109,12 @@
FRAMESET(BlockType.OTHER, EndKind.REQUIRED),
- H1,
- H2,
- H3,
- H4,
- H5,
- H6,
+ H1(BlockType.BLOCK, EndKind.REQUIRED),
+ H2(BlockType.BLOCK, EndKind.REQUIRED),
+ H3(BlockType.BLOCK, EndKind.REQUIRED),
+ H4(BlockType.BLOCK, EndKind.REQUIRED),
+ H5(BlockType.BLOCK, EndKind.REQUIRED),
+ H6(BlockType.BLOCK, EndKind.REQUIRED),
HEAD(BlockType.OTHER, EndKind.REQUIRED),
@@ -118,31 +130,54 @@
attrs(AttrKind.OBSOLETE, NAME),
attrs(AttrKind.USE_CSS, ALIGN, HSPACE, VSPACE, BORDER)),
- LI(BlockType.BLOCK, EndKind.OPTIONAL),
+ LI(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
LINK(BlockType.OTHER, EndKind.NONE),
- MENU,
+ MENU(BlockType.BLOCK, EndKind.REQUIRED) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == LI);
+ }
+ },
META(BlockType.OTHER, EndKind.NONE),
NOFRAMES(BlockType.OTHER, EndKind.REQUIRED),
- NOSCRIPT(BlockType.OTHER, EndKind.REQUIRED),
+ NOSCRIPT(BlockType.BLOCK, EndKind.REQUIRED),
OL(BlockType.BLOCK, EndKind.REQUIRED,
- EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
- attrs(AttrKind.USE_CSS, START, TYPE)),
+ EnumSet.of(Flag.EXPECT_CONTENT),
+ attrs(AttrKind.USE_CSS, START, TYPE)){
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == LI);
+ }
+ },
P(BlockType.BLOCK, EndKind.OPTIONAL,
EnumSet.of(Flag.EXPECT_CONTENT),
attrs(AttrKind.USE_CSS, ALIGN)),
- PRE(EnumSet.of(Flag.EXPECT_CONTENT)),
+ PRE(BlockType.BLOCK, EndKind.REQUIRED,
+ EnumSet.of(Flag.EXPECT_CONTENT)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ switch (t) {
+ case IMG: case BIG: case SMALL: case SUB: case SUP:
+ return false;
+ default:
+ return (t.blockType == BlockType.INLINE);
+ }
+ }
+ },
SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
- SMALL(BlockType.INLINE, EndKind.REQUIRED),
+ SMALL(BlockType.INLINE, EndKind.REQUIRED,
+ EnumSet.of(Flag.EXPECT_CONTENT)),
SPAN(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT)),
@@ -157,37 +192,70 @@
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
TABLE(BlockType.BLOCK, EndKind.REQUIRED,
- EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
+ EnumSet.of(Flag.EXPECT_CONTENT),
attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER,
CELLPADDING, CELLSPACING),
- attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)),
+ attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ switch (t) {
+ case CAPTION:
+ case THEAD: case TBODY: case TFOOT:
+ case TR: // HTML 3.2
+ return true;
+ default:
+ return false;
+ }
+ }
+ },
- TBODY(BlockType.BLOCK, EndKind.REQUIRED,
- EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
- attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+ TBODY(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+ EnumSet.of(Flag.EXPECT_CONTENT),
+ attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == TR);
+ }
+ },
- TD(BlockType.BLOCK, EndKind.OPTIONAL,
+ TD(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
ALIGN, CHAR, CHAROFF, VALIGN),
attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
- TFOOT(BlockType.BLOCK, EndKind.REQUIRED,
- attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+ TFOOT(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+ attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == TR);
+ }
+ },
- TH(BlockType.BLOCK, EndKind.OPTIONAL,
+ TH(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
+ EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
ALIGN, CHAR, CHAROFF, VALIGN),
attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
- THEAD(BlockType.BLOCK, EndKind.REQUIRED,
- attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+ THEAD(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+ attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == TR);
+ }
+ },
TITLE(BlockType.OTHER, EndKind.REQUIRED),
- TR(BlockType.BLOCK, EndKind.OPTIONAL,
- EnumSet.of(Flag.NO_TEXT),
+ TR(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN),
- attrs(AttrKind.USE_CSS, BGCOLOR)),
+ attrs(AttrKind.USE_CSS, BGCOLOR)) {
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == TH) || (t == TD);
+ }
+ },
TT(BlockType.INLINE, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
@@ -196,8 +264,13 @@
EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
UL(BlockType.BLOCK, EndKind.REQUIRED,
- EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
- attrs(AttrKind.USE_CSS, COMPACT, TYPE)),
+ EnumSet.of(Flag.EXPECT_CONTENT),
+ attrs(AttrKind.USE_CSS, COMPACT, TYPE)){
+ @Override
+ public boolean accepts(HtmlTag t) {
+ return (t == LI);
+ }
+ },
VAR(BlockType.INLINE, EndKind.REQUIRED);
@@ -207,6 +280,8 @@
public static enum BlockType {
BLOCK,
INLINE,
+ LIST_ITEM,
+ TABLE_ITEM,
OTHER;
}
@@ -220,9 +295,10 @@
}
public static enum Flag {
+ ACCEPTS_BLOCK,
+ ACCEPTS_INLINE,
EXPECT_CONTENT,
- NO_NEST,
- NO_TEXT
+ NO_NEST
}
public static enum Attr {
@@ -273,7 +349,7 @@
static final Map<String,Attr> index = new HashMap<String,Attr>();
static {
for (Attr t: values()) {
- index.put(t.name().toLowerCase(), t);
+ index.put(t.getText(), t);
}
}
}
@@ -300,22 +376,14 @@
public final Set<Flag> flags;
private final Map<Attr,AttrKind> attrs;
-
- HtmlTag() {
- this(BlockType.BLOCK, EndKind.REQUIRED);
- }
-
- HtmlTag(Set<Flag> flags) {
- this(BlockType.BLOCK, EndKind.REQUIRED, flags);
- }
-
HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) {
this(blockType, endKind, Collections.<Flag>emptySet(), attrMaps);
}
HtmlTag(BlockType blockType, EndKind endKind, Set<Flag> flags, AttrMap... attrMaps) {
this.blockType = blockType;
- this.endKind = endKind;this.flags = flags;
+ this.endKind = endKind;
+ this.flags = flags;
this.attrs = new EnumMap<Attr,AttrKind>(Attr.class);
for (Map<Attr,AttrKind> m: attrMaps)
this.attrs.putAll(m);
@@ -324,6 +392,35 @@
attrs.put(Attr.STYLE, AttrKind.OK);
}
+ public boolean accepts(HtmlTag t) {
+ if (flags.contains(Flag.ACCEPTS_BLOCK) && flags.contains(Flag.ACCEPTS_INLINE)) {
+ return (t.blockType == BlockType.BLOCK) || (t.blockType == BlockType.INLINE);
+ } else if (flags.contains(Flag.ACCEPTS_BLOCK)) {
+ return (t.blockType == BlockType.BLOCK);
+ } else if (flags.contains(Flag.ACCEPTS_INLINE)) {
+ return (t.blockType == BlockType.INLINE);
+ } else
+ switch (blockType) {
+ case BLOCK:
+ case INLINE:
+ return (t.blockType == BlockType.INLINE);
+ case OTHER:
+ // OTHER tags are invalid in doc comments, and will be
+ // reported separately, so silently accept/ignore any content
+ return true;
+ default:
+ // any combination which could otherwise arrive here
+ // ought to have been handled in an overriding method
+ throw new AssertionError(this + ":" + t);
+ }
+ }
+
+ public boolean acceptsText() {
+ // generally, anywhere we can put text we can also put inline tag
+ // so check if a typical inline tag is allowed
+ return accepts(B);
+ }
+
public String getText() {
return name().toLowerCase();
}
@@ -346,7 +443,7 @@
private static final Map<String,HtmlTag> index = new HashMap<String,HtmlTag>();
static {
for (HtmlTag t: values()) {
- index.put(t.name().toLowerCase(), t);
+ index.put(t.getText(), t);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Sat Jan 26 19:24:46 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
@@ -24,6 +24,7 @@
#
dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.value.missing = no value given for anchor
dc.attr.lacks.value = attribute lacks value
dc.attr.obsolete = attribute obsolete: {0}
dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0}
@@ -47,12 +48,14 @@
dc.no.summary.or.caption.for.table=no summary or caption for table
dc.param.name.not.found = @param name not found
dc.ref.not.found = reference not found
+dc.tag.code.within.code = '{@code'} within <code>
dc.tag.empty = empty <{0}> tag
dc.tag.end.not.permitted = invalid end tag: </{0}>
dc.tag.end.unexpected = unexpected end tag: </{0}>
dc.tag.header.sequence.1 = header used out of sequence: <{0}>
dc.tag.header.sequence.2 = header used out of sequence: <{0}>
dc.tag.nested.not.allowed=nested tag not allowed: <{0}>
+dc.tag.not.allowed.here = tag not allowed here: <{0}>
dc.tag.not.allowed = element not allowed in documentation comments: <{0}>
dc.tag.not.allowed.inline.element = block element not allowed within inline element <{1}>: {0}
dc.tag.not.allowed.inline.tag = block element not allowed within @{1}: {0}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Sat Jan 26 19:24:46 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
@@ -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().
*
* <p><b>This is NOT part of any supported API. If you write code that depends
* on this, you do so at your own risk. This code and its internal interfaces
@@ -67,14 +67,21 @@
*/
public class Annotations {
- private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
- private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
+ private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
+ private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
+
/*
* This field should never be null
*/
- private List<Attribute.Compound> attributes = NOT_STARTED;
+ private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
+
/*
- * The Symbol this Annotations belong to
+ * This field should never be null
+ */
+ private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * The Symbol this Annotations instance belongs to
*/
private final Symbol sym;
@@ -82,11 +89,15 @@
this.sym = sym;
}
- public List<Attribute.Compound> getAttributes() {
- return filterSentinels(attributes);
+ public List<Attribute.Compound> getDeclarationAttributes() {
+ return filterDeclSentinels(attributes);
}
- public void setAttributes(List<Attribute.Compound> a) {
+ public List<Attribute.TypeCompound> getTypeAttributes() {
+ return type_attributes;
+ }
+
+ public void setDeclarationAttributes(List<Attribute.Compound> a) {
Assert.check(pendingCompletion() || !isStarted());
if (a == null) {
throw new NullPointerException();
@@ -94,31 +105,51 @@
attributes = a;
}
+ public void setTypeAttributes(List<Attribute.TypeCompound> 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<Attribute.Compound> 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<Attribute.TypeCompound> ctx) {
+ this.appendUniqueTypes(getAttributesForCompletion(ctx));
+ }
- Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
+ private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
+ final Annotate.AnnotateRepeatedContext<T> ctx) {
+
+ Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
boolean atLeastOneRepeated = false;
- List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
- for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
+ List<T> buf = List.<T>nil();
+ for (ListBuffer<T> 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<T>(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
@@ -126,19 +157,18 @@
//
// We need to do this in two passes because when creating
// a container for a repeating annotation we must
- // guarantee that the @ContainedBy on the
+ // guarantee that the @Repeatable on the
// contained annotation is fully annotated
//
// The way we force this order is to do all repeating
// annotations in a pass after all non-repeating are
- // finished. This will work because @ContainedBy
+ // finished. This will work because @Repeatable
// is non-repeating and therefore will be annotated in the
// fist pass.
// Queue a pass that will replace Attribute.Placeholders
// with Attribute.Compound (made from synthesized containers).
ctx.annotateRepeated(new Annotate.Annotator() {
-
@Override
public String toString() {
return "repeated annotation pass of: " + 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<Attribute.Compound> l) {
- attributes = filterSentinels(attributes);
+ attributes = filterDeclSentinels(attributes);
if (l.isEmpty()) {
; // no-op
@@ -180,8 +216,24 @@
return this;
}
+ public Annotations appendUniqueTypes(List<Attribute.TypeCompound> 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<Attribute.Compound> l) {
- attributes = filterSentinels(attributes);
+ attributes = filterDeclSentinels(attributes);
if (l.isEmpty()) {
; // no-op
@@ -193,19 +245,29 @@
return this;
}
- private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
- return (a == IN_PROGRESS || a == NOT_STARTED)
+ private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
+ return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
? List.<Attribute.Compound>nil()
: a;
}
private boolean isStarted() {
- return attributes != NOT_STARTED;
+ return attributes != DECL_NOT_STARTED;
}
private List<Attribute.Compound> getPlaceholders() {
List<Attribute.Compound> res = List.<Attribute.Compound>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<Attribute.TypeCompound> getTypePlaceholders() {
+ List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
+ for (Attribute.TypeCompound a : type_attributes) {
if (a instanceof Placeholder) {
res = res.prepend(a);
}
@@ -216,68 +278,100 @@
/*
* Replace Placeholders for repeating annotations with their containers
*/
- private void complete(Annotate.AnnotateRepeatedContext ctx) {
- Assert.check(!pendingCompletion());
+ private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
Log log = ctx.log;
Env<AttrContext> 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<Attribute.Compound> result = List.nil();
- for (Attribute.Compound a : getAttributes()) {
- if (a instanceof Placeholder) {
- Attribute.Compound replacement = replaceOne((Placeholder) a, ctx);
+ List<Attribute.TypeCompound> result = List.nil();
+ for (Attribute.TypeCompound a : getTypeAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) 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<Attribute.Compound> result = List.nil();
+ for (Attribute.Compound a : getDeclarationAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Attribute.Compound replacement = replaceOne((Placeholder<T>) 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 extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> 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<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+ ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
if (manualContainer != null) {
- log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
manualContainer.first().type.tsym);
}
}
// A null return will delete the Placeholder
return validRepeated;
-
}
- private static class Placeholder extends Attribute.Compound {
+ private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
+
+ private final Annotate.AnnotateRepeatedContext<T> ctx;
+ private final List<T> placeholderFor;
+ private final Symbol on;
- private List<Attribute.Compound> placeholderFor;
- private Symbol on;
-
- public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
- super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
+ public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
+ super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
+ ctx.isTypeCompound ?
+ ((Attribute.TypeCompound)placeholderFor.head).position :
+ null);
+ this.ctx = ctx;
this.placeholderFor = placeholderFor;
this.on = on;
}
@@ -287,8 +381,12 @@
return "<placeholder: " + placeholderFor + " on: " + on + ">";
}
- public List<Attribute.Compound> getPlaceholderFor() {
+ public List<T> getPlaceholderFor() {
return placeholderFor;
}
+
+ public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
+ return ctx;
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Sat Jan 26 19:24:46 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<Pair<MethodSymbol, Attribute>> 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 {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Sat Jan 26 19:24:46 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;
@@ -280,7 +280,7 @@
SYNCHRONIZED | FINAL | STRICTFP;
public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
- InterfaceDefaultMethodMask = ABSTRACT | PUBLIC | STRICTFP | SYNCHRONIZED | DEFAULT,
+ InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
LocalVarFlags = FINAL | PARAMETER;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Sat Jan 26 19:24:46 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);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Sat Jan 26 19:24:46 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));
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Sat Jan 26 19:24:46 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;
}
@@ -206,18 +203,30 @@
public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowStaticInterfaceMethods() {
+ return compareTo(JDK1_8) >= 0;
+ }
public boolean allowStrictMethodClashCheck() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowTypeAnnotations() {
+ return compareTo(JDK1_8) >= 0;
+ }
public boolean allowRepeatedAnnotations() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowIntersectionTypesInCast() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowEarlyReturnConstraints() {
+ return compareTo(JDK1_8) >= 0;
+ }
+ public boolean allowStructuralMostSpecific() {
+ return compareTo(JDK1_8) >= 0;
+ }
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Sat Jan 26 19:24:46 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
@@ -84,7 +84,15 @@
* method to make sure that the class symbol is loaded.
*/
public List<Attribute.Compound> 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<Attribute.TypeCompound> getRawTypeAttributes() {
+ return annotations.getTypeAttributes();
}
/** Fetch a particular annotation from a symbol. */
@@ -450,11 +458,19 @@
* This is the implementation for {@code
* javax.lang.model.element.Element.getAnnotationMirrors()}.
*/
- public final List<Attribute.Compound> getAnnotationMirrors() {
+ public final List<? extends AnnotationMirror> getAnnotationMirrors() {
return getRawAttributes();
}
/**
+ * TODO: Should there be a {@code
+ * javax.lang.model.element.Element.getTypeAnnotationMirrors()}.
+ */
+ public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
+ return getRawTypeAttributes();
+ }
+
+ /**
* @deprecated this method should never be used by javac internally.
*/
@Deprecated
@@ -462,6 +478,11 @@
return JavacElements.getAnnotation(this, annoType);
}
+ // This method is part of the javax.lang.model API, do not use this in javac code.
+ public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) {
+ return JavacElements.getAnnotations(this, annoType);
+ }
+
// TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
public java.util.List<Symbol> getEnclosedElements() {
return List.nil();
@@ -790,6 +811,12 @@
return super.getRawAttributes();
}
+ @Override
+ public List<Attribute.TypeCompound> 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()),
@@ -1228,7 +1255,8 @@
case Flags.PRIVATE:
return false;
case Flags.PUBLIC:
- return true;
+ return !this.owner.isInterface() ||
+ (flags_field & STATIC) == 0;
case Flags.PROTECTED:
return (origin.flags() & INTERFACE) == 0;
case 0:
@@ -1242,6 +1270,18 @@
}
}
+ @Override
+ public boolean isInheritedIn(Symbol clazz, Types types) {
+ switch ((int)(flags_field & Flags.AccessFlags)) {
+ case PUBLIC:
+ return !this.owner.isInterface() ||
+ clazz == owner ||
+ (flags_field & STATIC) == 0;
+ default:
+ return super.isInheritedIn(clazz, types);
+ }
+ }
+
/** The implementation of this (abstract) symbol in class origin;
* null if none exists. Synthetic methods are not considered
* as possible implementations.
@@ -1369,7 +1409,7 @@
return defaultValue;
}
- public List<VarSymbol> getParameters() {
+ public List<VarSymbol> getParameters() {
return params();
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Sat Jan 26 19:24:46 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
@@ -161,10 +161,10 @@
public final Type autoCloseableType;
public final Type trustMeType;
public final Type lambdaMetafactory;
- public final Type containedByType;
- public final Type containerForType;
+ public final Type repeatableType;
public final Type documentedType;
public final Type elementTypeType;
+ public final Type functionalInterfaceType;
/** The symbol representing the length field of an array.
*/
@@ -494,8 +494,7 @@
deprecatedType = enterClass("java.lang.Deprecated");
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
inheritedType = enterClass("java.lang.annotation.Inherited");
- containedByType = enterClass("java.lang.annotation.ContainedBy");
- containerForType = enterClass("java.lang.annotation.ContainerFor");
+ repeatableType = enterClass("java.lang.annotation.Repeatable");
documentedType = enterClass("java.lang.annotation.Documented");
elementTypeType = enterClass("java.lang.annotation.ElementType");
systemType = enterClass("java.lang.System");
@@ -509,6 +508,7 @@
nativeHeaderType = enterClass("java.lang.annotation.Native");
nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
+ functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java Sat Jan 26 19:24:46 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.</b>
*/
+// 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<TargetAttribute> 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;
- }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Sat Jan 26 19:24:46 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<Type> baseTypes(List<Type> 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<? extends AnnotationMirror> getAnnotations() { return List.nil(); }
public List<Type> getTypeArguments() { return List.nil(); }
- public Type getEnclosingType() { return null; }
+ public Type getEnclosingType() { return null; }
public List<Type> getParameterTypes() { return List.nil(); }
public Type getReturnType() { return null; }
+ public Type getReceiverType() { return null; }
public List<Type> 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<Type> thrown;
+ /** The type annotations on the method receiver.
+ */
+ public Type recvtype;
+
public MethodType(List<Type> argtypes,
Type restype,
List<Type> thrown,
@@ -1000,6 +1018,7 @@
public List<Type> getParameterTypes() { return argtypes; }
public Type getReturnType() { return restype; }
+ public Type getReceiverType() { return recvtype; }
public List<Type> getThrownTypes() { return thrown; }
public boolean isErroneous() {
@@ -1028,6 +1047,7 @@
for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
l.head.complete();
restype.complete();
+ recvtype.complete();
for (List<Type> 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<Type> getParameterTypes() { return qtype.getParameterTypes(); }
public Type getReturnType() { return qtype.getReturnType(); }
+ public Type getReceiverType() { return qtype.getReceiverType(); }
public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
public List<Type> 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<Attribute.TypeCompound> 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<Attribute.TypeCompound> 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<? extends AnnotationMirror> getAnnotations() {
+ return typeAnnotations;
+ }
+
+ @Override
+ public TypeMirror getUnderlyingType() {
+ return underlyingType;
+ }
+
+ @Override
+ public Type unannotatedType() {
+ return underlyingType;
+ }
+
+ @Override
+ public <R,S> R accept(Type.Visitor<R,S> v, S s) {
+ return v.visitAnnotatedType(this, s);
+ }
+
+ @Override
+ public <R, P> R accept(TypeVisitor<R, P> 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<Type> getTypeArguments() { return underlyingType.getTypeArguments(); }
+ @Override
+ public List<Type> getParameterTypes() { return underlyingType.getParameterTypes(); }
+ @Override
+ public Type getReceiverType() { return underlyingType.getReceiverType(); }
+ @Override
+ public List<Type> 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<Type> 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.
* <!-- In plain text: Type x 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);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Sat Jan 26 19:24:46 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.</b>
*/
+// 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<Integer> location = List.nil();
+ public List<TypePathEntry> 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<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
+ ListBuffer<TypePathEntry> loc = ListBuffer.lb();
+ Iterator<Integer> 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<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
+ ListBuffer<Integer> loc = ListBuffer.lb();
+ for (TypePathEntry tpe : locs) {
+ loc = loc.append(tpe.tag.tag);
+ loc = loc.append(tpe.arg);
+ }
+ return loc.toList();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Sat Jan 26 19:24:46 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<JCTree> 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<Attribute.Compound> annotations = sym.getRawAttributes();
+ ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>();
+ ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
+
+ 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<Attribute.TypeCompound> 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<JCTypeAnnotation>, 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<Attribute.TypeCompound> 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<TypePathEntry> 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<TypePathEntry> 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<Attribute.TypeCompound> annotations) {
+ Visitor<Type, List<TypeCompound>> visitor =
+ new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
+ @Override
+ public Type visitClassType(ClassType t, List<TypeCompound> 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<TypeCompound> s) {
+ return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s));
+ }
+
+ @Override
+ public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
+ return new AnnotatedType(s, t);
+ }
+
+ @Override
+ public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
+ ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym);
+ return ret;
+ }
+
+ @Override
+ public Type visitMethodType(MethodType t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitPackageType(PackageType t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
+ return new AnnotatedType(s, t);
+ }
+
+ @Override
+ public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
+ return new AnnotatedType(s, t);
+ }
+
+ @Override
+ public Type visitForAll(ForAll t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
+ return new AnnotatedType(s, t);
+ }
+
+ @Override
+ public Type visitType(Type t, List<TypeCompound> 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<JCTree> 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<JCTree> newPath = path.tail;
+ resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+ return;
+ }
+
+ case ARRAY_TYPE: {
+ ListBuffer<TypePathEntry> index = ListBuffer.lb();
+ index = index.append(TypePathEntry.ARRAY);
+ List<JCTree> 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<JCTree> 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<JCTree> 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<JCTree> newPath = path.tail;
+ resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+ return;
+ }
+
+ case MEMBER_SELECT: {
+ List<JCTree> 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<TypePathEntry> 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<JCTree> path, JCTree param) {
+ List<JCTree> 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<TypePathEntry> 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<JCAnnotation> 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<JCAnnotation> annotations,
+ TypeAnnotationPosition position) {
+ for (JCAnnotation anno : annotations) {
+ ((Attribute.TypeCompound) anno.attribute).position = position;
+ }
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sat Jan 26 19:24:46 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.*;
@@ -354,8 +355,29 @@
return descSym;
}
- public Type getType(Type origin) {
- return memberType(origin, descSym);
+ public Type getType(Type site) {
+ if (capture(site) != site) {
+ Type formalInterface = site.tsym.type;
+ ListBuffer<Type> typeargs = ListBuffer.lb();
+ List<Type> actualTypeargs = site.getTypeArguments();
+ //simply replace the wildcards with its bound
+ for (Type t : formalInterface.getTypeArguments()) {
+ if (actualTypeargs.head.hasTag(WILDCARD)) {
+ WildcardType wt = (WildcardType)actualTypeargs.head;
+ typeargs.append(wt.type);
+ } else {
+ typeargs.append(actualTypeargs.head);
+ }
+ actualTypeargs = actualTypeargs.tail;
+ }
+ site = subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
+ if (!chk.checkValidGenericType(site)) {
+ //if the inferred functional interface type is not well-formed,
+ //or if it's not a subtype of the original target, issue an error
+ throw failure(diags.fragment("no.suitable.functional.intf.inst", site));
+ }
+ }
+ return memberType(site, descSym);
}
}
@@ -392,9 +414,9 @@
* Compute the function descriptor associated with a given functional interface
*/
public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
- if (!origin.isInterface()) {
+ if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
//t must be an interface
- throw failure("not.a.functional.intf");
+ throw failure("not.a.functional.intf", origin);
}
final ListBuffer<Symbol> abstracts = ListBuffer.lb();
@@ -406,13 +428,13 @@
abstracts.append(sym);
} else {
//the target method(s) should be the only abstract members of t
- throw failure("not.a.functional.intf.1",
+ throw failure("not.a.functional.intf.1", origin,
diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin));
}
}
if (abstracts.isEmpty()) {
//t must define a suitable non-generic method
- throw failure("not.a.functional.intf.1",
+ throw failure("not.a.functional.intf.1", origin,
diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
} else if (abstracts.size() == 1) {
return new FunctionDescriptor(abstracts.first());
@@ -553,6 +575,15 @@
return false;
}
}
+
+ public boolean isFunctionalInterface(Type site) {
+ try {
+ findDescriptorType(site);
+ return true;
+ } catch (FunctionDescriptorLookupError ex) {
+ return false;
+ }
+ }
// </editor-fold>
/**
@@ -654,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 {
@@ -679,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) {
@@ -712,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);
@@ -1653,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);
@@ -1981,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") {
@@ -2923,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;
@@ -3624,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;
@@ -4142,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); }
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Sat Jan 26 19:24:46 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
@@ -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<Annotator> q = new ListBuffer<Annotator>();
+ ListBuffer<Annotator> typesQ = new ListBuffer<Annotator>();
ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
+ ListBuffer<Annotator> afterRepeatedQ = new ListBuffer<Annotator>();
+
+ 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<T extends Attribute.Compound> {
public final Env<AttrContext> env;
- public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
- public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
+ public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated;
+ public final Map<T, JCDiagnostic.DiagnosticPosition> pos;
public final Log log;
+ public final boolean isTypeCompound;
public AnnotateRepeatedContext(Env<AttrContext> env,
- Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
- Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
- Log log) {
+ Map<Symbol.TypeSymbol, ListBuffer<T>> annotated,
+ Map<T, JCDiagnostic.DiagnosticPosition> 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<Attribute.Compound> repeatingAnnotations, Symbol sym) {
+ public T processRepeatedAnnotations(List<T> 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<AttrContext> env) {
+ Attribute.Compound c = enterAnnotation(a, expected, env);
+ Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
+ a.attribute = tc;
+ return tc;
+ }
+
/* *********************************
* Support for repeating annotations
***********************************/
@@ -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<Attribute.Compound> annotations,
- AnnotateRepeatedContext ctx,
- Symbol on) {
- Attribute.Compound firstOccurrence = annotations.head;
+ private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
+ AnnotateRepeatedContext<T> ctx,
+ Symbol on) {
+ T firstOccurrence = annotations.head;
List<Attribute> 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<Attribute.Compound> al = annotations;
+ for (List<T> 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<MethodSymbol, Attribute> p =
new Pair<MethodSymbol, Attribute>(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.containedby.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
}
@@ -414,11 +469,11 @@
Type origAnnoType = currentAnno.type;
TypeSymbol origAnnoDecl = origAnnoType.tsym;
- // Fetch the ContainedBy annotation from the current
+ // Fetch the Repeatable annotation from the current
// annotation's declaration, or null if it has none
- Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
- if (ca == null) { // has no ContainedBy annotation
- log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType);
+ Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
+ if (ca == null) { // has no Repeatable annotation
+ log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
return null;
}
@@ -440,23 +495,23 @@
DiagnosticPosition pos,
TypeSymbol annoDecl)
{
- // The next three checks check that the ContainedBy annotation
+ // The next three checks check that the Repeatable annotation
// on the declaration of the annotation type that is repeating is
// valid.
- // ContainedBy must have at least one element
+ // Repeatable must have at least one element
if (ca.values.isEmpty()) {
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
Pair<MethodSymbol,Attribute> p = ca.values.head;
Name name = p.fst.name;
if (name != names.value) { // should contain only one element, named "value"
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
@@ -491,13 +546,13 @@
}
if (error) {
log.error(pos,
- "invalid.containedby.annotation.multiple.values",
+ "invalid.repeatable.annotation.multiple.values",
targetContainerType,
nr_value_elems);
return null;
} else if (nr_value_elems == 0) {
log.error(pos,
- "invalid.containedby.annotation.no.value",
+ "invalid.repeatable.annotation.no.value",
targetContainerType);
return null;
}
@@ -506,7 +561,7 @@
// probably "impossible" to fail this
if (containerValueSymbol.kind != Kinds.MTH) {
log.error(pos,
- "invalid.containedby.annotation.invalid.value",
+ "invalid.repeatable.annotation.invalid.value",
targetContainerType);
fatalError = true;
}
@@ -518,7 +573,7 @@
if (!(types.isArray(valueRetType) &&
types.isSameType(expectedType, valueRetType))) {
log.error(pos,
- "invalid.containedby.annotation.value.return",
+ "invalid.repeatable.annotation.value.return",
targetContainerType,
valueRetType,
expectedType);
@@ -528,10 +583,7 @@
fatalError = true;
}
- // Explicitly no check for/validity of @ContainerFor. That is
- // done on declaration of the container, and at reflect time.
-
- // The rest of the conditions for a valid containing annotation are made
+ // The conditions for a valid containing annotation are made
// in Check.validateRepeatedAnnotaton();
return fatalError ? null : containerValueSymbol;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Sat Jan 26 19:24:46 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,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,9 +45,9 @@
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.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
@@ -879,6 +879,7 @@
deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), m);
+
// Create a new environment with local scope
// for attributing the method.
Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
@@ -922,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<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
+ attribType(tree.recvparam, newEnv);
+ chk.validate(tree.recvparam, newEnv);
+ if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
+ // The == covers the common non-generic case, but for generic classes we need isSameType;
+ // note that equals didn't work.
+ log.error(tree.recvparam.pos(), "incorrect.receiver.type");
+ }
+ }
+
// annotation method checks
if ((owner.flags() & ANNOTATION) != 0) {
// annotation method cannot have throws clause
@@ -953,8 +969,7 @@
// Empty bodies are only allowed for
// abstract, native, or interface methods, or for methods
// in a retrofit signature class.
- if (isDefaultMethod || ((owner.flags() & INTERFACE) == 0 &&
- (tree.mods.flags & (ABSTRACT | NATIVE)) == 0) &&
+ if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
!relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
@@ -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.
@@ -1376,18 +1407,19 @@
public void visitConditional(JCConditional tree) {
Type condtype = attribExpr(tree.cond, env, syms.booleanType);
- boolean standaloneConditional = !allowPoly ||
+ tree.polyKind = (!allowPoly ||
pt().hasTag(NONE) && pt() != Type.recoveryType ||
- isBooleanOrNumeric(env, tree);
-
- if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
+ isBooleanOrNumeric(env, tree)) ?
+ PolyKind.STANDALONE : PolyKind.POLY;
+
+ if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
//cannot get here (i.e. it means we are returning from void method - which is already an error)
resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
result = tree.type = types.createErrorType(resultInfo.pt);
return;
}
- ResultInfo condInfo = standaloneConditional ?
+ ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
unknownExprInfo :
resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
//this will use enclosing check context to check compatibility of
@@ -1402,7 +1434,7 @@
Type truetype = attribTree(tree.truepart, env, condInfo);
Type falsetype = attribTree(tree.falsepart, env, condInfo);
- Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
+ Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt();
if (condtype.constValue() != null &&
truetype.constValue() != null &&
falsetype.constValue() != null &&
@@ -1424,12 +1456,30 @@
JCConditional condTree = (JCConditional)tree;
return isBooleanOrNumeric(env, condTree.truepart) &&
isBooleanOrNumeric(env, condTree.falsepart);
+ case APPLY:
+ JCMethodInvocation speculativeMethodTree =
+ (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
+ Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
+ return types.unboxedTypeOrType(owntype).isPrimitive();
+ case NEWCLASS:
+ JCExpression className =
+ removeClassParams.translate(((JCNewClass)tree).clazz);
+ JCExpression speculativeNewClassTree =
+ (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
+ return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
default:
Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
speculativeType = types.unboxedTypeOrType(speculativeType);
return speculativeType.isPrimitive();
}
}
+ //where
+ TreeTranslator removeClassParams = new TreeTranslator() {
+ @Override
+ public void visitTypeApply(JCTypeApply tree) {
+ result = translate(tree.clazz);
+ }
+ };
/** Compute the type of a conditional expression, after
* checking that it exists. See JLS 15.25. Does not take into
@@ -1828,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
@@ -1846,14 +1910,30 @@
// yields a clazz T.C.
Type encltype = chk.checkRefType(tree.encl.pos(),
attribExpr(tree.encl, env));
+ // TODO 308: in <expr>.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<JCAnnotation> 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
@@ -1870,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");
@@ -2173,17 +2256,18 @@
boolean needsRecovery =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
+ Type target = pt();
List<Type> explicitParamTypes = null;
- if (TreeInfo.isExplicitLambda(that)) {
+ if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
attribStats(that.params, localEnv);
explicitParamTypes = TreeInfo.types(that.params);
+ target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
}
- Type target;
Type lambdaType;
if (pt() != Type.recoveryType) {
- target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), explicitParamTypes, resultInfo.checkContext);
+ target = checkIntersectionTarget(that, target, resultInfo.checkContext);
lambdaType = types.findDescriptorType(target);
chk.checkFunctionalInterface(that, target);
} else {
@@ -2191,6 +2275,8 @@
lambdaType = fallbackDescriptorType(that);
}
+ setFunctionalInfo(that, pt(), lambdaType, resultInfo.checkContext.inferenceContext());
+
if (lambdaType.hasTag(FORALL)) {
//lambda expression target desc cannot be a generic method
resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
@@ -2199,7 +2285,7 @@
return;
}
- if (!TreeInfo.isExplicitLambda(that)) {
+ if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
//add param type info in the AST
List<Type> actuals = lambdaType.getParameterTypes();
List<JCVariableDecl> params = that.params;
@@ -2282,8 +2368,7 @@
}
}
- private Type checkIntersectionTarget(DiagnosticPosition pos, ResultInfo resultInfo) {
- Type pt = resultInfo.pt;
+ private Type checkIntersectionTarget(DiagnosticPosition pos, Type pt, CheckContext checkContext) {
if (pt != Type.recoveryType && pt.isCompound()) {
IntersectionClassType ict = (IntersectionClassType)pt;
List<Type> bounds = ict.allInterfaces ?
@@ -2292,7 +2377,7 @@
types.findDescriptorType(bounds.head); //propagate exception outwards!
for (Type bound : bounds.tail) {
if (!types.isMarkerInterface(bound)) {
- resultInfo.checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
+ checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
}
}
//for now (translation doesn't support intersection types)
@@ -2355,9 +2440,9 @@
@Override
public boolean compatible(Type found, Type req, Warner warn) {
//return type must be compatible in both current context and assignment context
- return types.isAssignable(found, inferenceContext().asFree(req, types), warn) &&
- super.compatible(found, req, warn);
+ return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn);
}
+
@Override
public void report(DiagnosticPosition pos, JCDiagnostic details) {
enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details));
@@ -2473,7 +2558,7 @@
Type target;
Type desc;
if (pt() != Type.recoveryType) {
- target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), null, resultInfo.checkContext);
+ target = checkIntersectionTarget(that, pt(), resultInfo.checkContext);
desc = types.findDescriptorType(target);
chk.checkFunctionalInterface(that, target);
} else {
@@ -2481,12 +2566,11 @@
desc = fallbackDescriptorType(that);
}
+ setFunctionalInfo(that, pt(), desc, resultInfo.checkContext.inferenceContext());
List<Type> argtypes = desc.getParameterTypes();
- boolean allowBoxing =
- resultInfo.checkContext.deferredAttrContext().phase.isBoxingRequired();
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = rs.resolveMemberReference(that.pos(), localEnv, that,
- that.expr.type, that.name, argtypes, typeargtypes, allowBoxing);
+ that.expr.type, that.name, argtypes, typeargtypes, true);
Symbol refSym = refResult.fst;
Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
@@ -2635,6 +2719,34 @@
}
}
+ /**
+ * Set functional type info on the underlying AST. Note: as the target descriptor
+ * might contain inference variables, we might need to register an hook in the
+ * current inference context.
+ */
+ private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) {
+ if (inferenceContext.free(descriptorType)) {
+ inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
+ public void typesInferred(InferenceContext inferenceContext) {
+ setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext);
+ }
+ });
+ } else {
+ ListBuffer<TypeSymbol> targets = ListBuffer.lb();
+ if (pt.hasTag(CLASS)) {
+ if (pt.isCompound()) {
+ for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
+ targets.append(t.tsym);
+ }
+ } else {
+ targets.append(pt.tsym);
+ }
+ }
+ fExpr.targets = targets.toList();
+ fExpr.descriptorType = descriptorType;
+ }
+ }
+
public void visitParens(JCParens tree) {
Type owntype = attribTree(tree.expr, env, resultInfo);
result = check(tree, owntype, pkind(), resultInfo);
@@ -3207,8 +3319,18 @@
// Tree<Point>.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)
@@ -3432,6 +3554,15 @@
env.info.defaultSuperCallSite = null;
}
+ if (sym.isStatic() && site.isInterface()) {
+ Assert.check(env.tree.hasTag(APPLY));
+ JCMethodInvocation app = (JCMethodInvocation)env.tree;
+ if (app.meth.hasTag(SELECT) &&
+ !TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) {
+ log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
+ }
+ }
+
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
@@ -3587,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);
@@ -3684,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<JCAnnotation> annotations) {
+ if (annotations.isEmpty())
+ return;
+ annotate.typeAnnotation(new Annotate.Annotator() {
+ @Override
+ public String toString() {
+ return "annotate " + annotations + " onto " + type;
+ }
+ @Override
+ public void enterAnnotation() {
+ List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
+ type.typeAnnotations = compounds;
+ }
+ });
+ }
+
+ private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
+ if (annotations.isEmpty())
+ return List.nil();
+
+ ListBuffer<Attribute.TypeCompound> 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)
@@ -3844,24 +4020,14 @@
log.error(tree.typarams.head.pos(),
"intf.annotation.cant.have.type.params");
- // If this annotation has a @ContainedBy, validate
- Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
- if (containedBy != null) {
- // get diagnositc position for error reporting
- DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+ // If this annotation has a @Repeatable, validate
+ Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym);
+ if (repeatable != null) {
+ // get diagnostic position for error reporting
+ DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
Assert.checkNonNull(cbPos);
- chk.validateContainedBy(c, containedBy, cbPos);
- }
-
- // If this annotation has a @ContainerFor, validate
- Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
- if (containerFor != null) {
- // get diagnositc position for error reporting
- DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
- Assert.checkNonNull(cfPos);
-
- chk.validateContainerFor(c, containerFor, cfPos);
+ chk.validateRepeatable(c, repeatable, cbPos);
}
} else {
// Check that all extended classes and interfaces
@@ -3925,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 */
@@ -3982,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");
+ }
+ }
+ };
+
// <editor-fold desc="post-attribution visitor">
/**
@@ -4088,11 +4348,28 @@
}
@Override
+ public void visitLambda(JCLambda that) {
+ super.visitLambda(that);
+ if (that.descriptorType == null) {
+ that.descriptorType = syms.unknownType;
+ }
+ if (that.targets == null) {
+ that.targets = List.nil();
+ }
+ }
+
+ @Override
public void visitReference(JCMemberReference that) {
super.visitReference(that);
if (that.sym == null) {
that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol);
}
+ if (that.descriptorType == null) {
+ that.descriptorType = syms.unknownType;
+ }
+ if (that.targets == null) {
+ that.targets = List.nil();
+ }
}
}
// </editor-fold>
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sat Jan 26 19:24:46 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,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.*;
@@ -36,7 +36,6 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.code.Lint;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Type.*;
@@ -44,6 +43,8 @@
import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.ANNOTATION;
@@ -100,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);
@@ -571,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.
*
@@ -634,25 +631,40 @@
}
}
+ Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
+ if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
+ return typeTagError(pos,
+ diags.fragment("type.req.class.array"),
+ asTypeParam(t));
+ } else {
+ return t;
+ }
+ }
+
/** Check that type is a class or interface type.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkClassType(DiagnosticPosition pos, Type t) {
- if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
+ if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
return typeTagError(pos,
diags.fragment("type.req.class"),
- (t.hasTag(TYPEVAR))
- ? diags.fragment("type.parameter", t)
- : t);
- else
+ asTypeParam(t));
+ } else {
return t;
+ }
}
+ //where
+ private Object asTypeParam(Type t) {
+ return (t.hasTag(TYPEVAR))
+ ? diags.fragment("type.parameter", t)
+ : t;
+ }
/** Check that type is a valid qualifier for a constructor reference expression
*/
Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
- t = checkClassType(pos, t);
+ t = checkClassOrArrayType(pos, t);
if (t.hasTag(CLASS)) {
if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
log.error(pos, "abstract.cant.be.instantiated");
@@ -690,11 +702,8 @@
* @param t The type to be checked.
*/
Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
- if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
- return typeTagError(pos,
- diags.fragment("type.req.class.array"),
- t);
- } else if (!types.isReifiable(t)) {
+ t = checkClassOrArrayType(pos, t);
+ if (!t.isErroneous() && !types.isReifiable(t)) {
log.error(pos, "illegal.generic.type.for.instof");
return types.createErrorType(t);
} else {
@@ -840,7 +849,7 @@
// System.out.println("actuals: " + argtypes);
List<Type> 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<JCExpression> args = argtrees;
@@ -888,7 +897,6 @@
syms.methodClass);
}
if (useVarargs) {
- JCTree tree = env.tree;
Type argtype = owntype.getParameterTypes().last();
if (!types.isReifiable(argtype) &&
(!allowSimplifiedVarargs ||
@@ -899,22 +907,13 @@
argtype);
}
if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
- Type elemtype = types.elemtype(argtype);
- switch (tree.getTag()) {
- case APPLY:
- ((JCMethodInvocation) tree).varargsElement = elemtype;
- break;
- case NEWCLASS:
- ((JCNewClass) tree).varargsElement = elemtype;
- break;
- case REFERENCE:
- ((JCMemberReference) tree).varargsElement = elemtype;
- break;
- default:
- throw new AssertionError(""+tree);
- }
+ TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
}
}
+ PolyKind pkind = (sym.type.hasTag(FORALL) &&
+ sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
+ PolyKind.POLY : PolyKind.STANDALONE;
+ TreeInfo.setPolyKind(env.tree, pkind);
return owntype;
}
//where
@@ -1055,9 +1054,12 @@
} else
mask = ConstructorFlags;
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
- if ((flags & DEFAULT) != 0) {
- mask = InterfaceDefaultMethodMask;
- implicit = PUBLIC | ABSTRACT;
+ if ((flags & (DEFAULT | STATIC)) != 0) {
+ mask = InterfaceMethodMask;
+ implicit = PUBLIC;
+ if ((flags & DEFAULT) != 0) {
+ implicit |= ABSTRACT;
+ }
} else {
mask = implicit = InterfaceMethodFlags;
}
@@ -1127,6 +1129,10 @@
PRIVATE | STATIC | DEFAULT))
&&
checkDisjoint(pos, flags,
+ STATIC,
+ DEFAULT)
+ &&
+ checkDisjoint(pos, flags,
ABSTRACT | INTERFACE,
FINAL | NATIVE | SYNCHRONIZED)
&&
@@ -1316,6 +1322,11 @@
}
}
+ @Override
+ public void visitAnnotatedType(JCAnnotatedType tree) {
+ tree.underlyingType.accept(this);
+ }
+
/** Default visitor method: do nothing.
*/
@Override
@@ -2236,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.
*/
@@ -2577,6 +2588,13 @@
validateAnnotation(a, s);
}
+ /** Check the type annotations.
+ */
+ public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
+ for (JCAnnotation a : annotations)
+ validateTypeAnnotation(a, isTypeParameter);
+ }
+
/** Check an annotation of a symbol.
*/
private void validateAnnotation(JCAnnotation a, Symbol s) {
@@ -2589,33 +2607,53 @@
if (!isOverrider(s))
log.error(a.pos(), "method.does.not.override.superclass");
}
+
+ if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
+ if (s.kind != TYP) {
+ log.error(a.pos(), "bad.functional.intf.anno");
+ } else {
+ try {
+ types.findDescriptorSymbol((TypeSymbol)s);
+ } catch (Types.FunctionDescriptorLookupError ex) {
+ log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
+ }
+ }
+ }
+ }
+
+ 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 'containedBy' on the
+ * Validate the proposed container 'repeatable' on the
* annotation type symbol 's'. Report errors at position
* 'pos'.
*
- * @param s The (annotation)type declaration annotated with a @ContainedBy
- * @param containedBy the @ContainedBy on 's'
+ * @param s The (annotation)type declaration annotated with a @Repeatable
+ * @param repeatable the @Repeatable on 's'
* @param pos where to report errors
*/
- public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
- Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+ public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
if (!l.isEmpty()) {
Assert.check(l.head.fst.name == names.value);
t = ((Attribute.Class)l.head.snd).getValue();
}
if (t == null) {
- log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+ // errors should already have been reported during Annotate
return;
}
- validateHasContainerFor(t.tsym, s, pos);
+ validateValue(t.tsym, s, pos);
validateRetention(t.tsym, s, pos);
validateDocumented(t.tsym, s, pos);
validateInherited(t.tsym, s, pos);
@@ -2623,79 +2661,18 @@
validateDefault(t.tsym, s, pos);
}
- /**
- * Validate the proposed container 'containerFor' on the
- * annotation type symbol 's'. Report errors at position
- * 'pos'.
- *
- * @param s The (annotation)type declaration annotated with a @ContainerFor
- * @param containerFor the @ContainedFor on 's'
- * @param pos where to report errors
- */
- public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
- Assert.check(types.isSameType(containerFor.type, syms.containerForType));
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
- return;
- }
-
- validateHasContainedBy(t.tsym, s, pos);
- }
-
- private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
- Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
-
- if (containedBy == null) {
- log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
- return;
+ private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Scope.Entry e = container.members().lookup(names.value);
+ if (e.scope != null && e.sym.kind == MTH) {
+ MethodSymbol m = (MethodSymbol) e.sym;
+ Type ret = m.getReturnType();
+ if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
+ log.error(pos, "invalid.repeatable.annotation.value.return",
+ container, ret, types.makeArrayType(contained.type));
+ }
+ } else {
+ log.error(pos, "invalid.repeatable.annotation.no.value", container);
}
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containedby", container, contained);
- return;
- }
-
- if (!types.isSameType(t, contained.type))
- log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
- }
-
- private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
- Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
-
- if (containerFor == null) {
- log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
- return;
- }
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containerfor", container, contained);
- return;
- }
-
- if (!types.isSameType(t, contained.type))
- log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
}
private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
@@ -2715,7 +2692,7 @@
}
}
if (error ) {
- log.error(pos, "invalid.containedby.annotation.retention",
+ log.error(pos, "invalid.repeatable.annotation.retention",
container, containerRetention,
contained, containedRetention);
}
@@ -2724,7 +2701,7 @@
private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
if (contained.attribute(syms.documentedType.tsym) != null) {
if (container.attribute(syms.documentedType.tsym) == null) {
- log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
}
}
}
@@ -2732,7 +2709,7 @@
private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
if (contained.attribute(syms.inheritedType.tsym) != null) {
if (container.attribute(syms.inheritedType.tsym) == null) {
- log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
}
}
}
@@ -2752,7 +2729,7 @@
// contained has target, but container has not, error
Attribute.Array containerTarget = getAttributeTargetAttribute(container);
if (containerTarget == null) {
- log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
return;
}
@@ -2775,7 +2752,7 @@
}
if (!isTargetSubset(containedTargets, containerTargets)) {
- log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
}
}
@@ -2809,7 +2786,7 @@
elm.kind == Kinds.MTH &&
((MethodSymbol)elm).defaultValue == null) {
log.error(pos,
- "invalid.containedby.annotation.elem.nondefault",
+ "invalid.repeatable.annotation.elem.nondefault",
container,
elm);
}
@@ -2834,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<arr.values.length; ++i) {
+ Attribute app = arr.values[i];
+ if (!(app instanceof Attribute.Enum)) {
+ return true; // recovery
+ }
+ Attribute.Enum e = (Attribute.Enum) app;
+ targets[i] = e.value.name;
+ }
}
- for (Attribute app : arr.values) {
- if (!(app instanceof Attribute.Enum)) return true; // recovery
- Attribute.Enum e = (Attribute.Enum) app;
- if (e.value.name == names.TYPE)
+ for (Name target : targets) {
+ if (target == names.TYPE)
{ if (s.kind == TYP) return true; }
- else if (e.value.name == names.FIELD)
+ else if (target == names.FIELD)
{ if (s.kind == VAR && s.owner.kind != MTH) return true; }
- else if (e.value.name == names.METHOD)
+ else if (target == names.METHOD)
{ if (s.kind == MTH && !s.isConstructor()) return true; }
- else if (e.value.name == names.PARAMETER)
+ else if (target == names.PARAMETER)
{ if (s.kind == VAR &&
s.owner.kind == MTH &&
(s.flags() & PARAMETER) != 0)
return true;
}
- else if (e.value.name == names.CONSTRUCTOR)
+ else if (target == names.CONSTRUCTOR)
{ if (s.kind == MTH && s.isConstructor()) return true; }
- else if (e.value.name == names.LOCAL_VARIABLE)
+ else if (target == names.LOCAL_VARIABLE)
{ if (s.kind == VAR && s.owner.kind == MTH &&
(s.flags() & PARAMETER) == 0)
return true;
}
- else if (e.value.name == names.ANNOTATION_TYPE)
+ else if (target == names.ANNOTATION_TYPE)
{ if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
return true;
}
- else if (e.value.name == names.PACKAGE)
+ else if (target == names.PACKAGE)
{ if (s.kind == PCK) return true; }
- else if (e.value.name == names.TYPE_USE)
+ else if (target == names.TYPE_USE)
{ if (s.kind == TYP ||
s.kind == VAR ||
(s.kind == MTH && !s.isConstructor() &&
- !s.type.getReturnType().hasTag(VOID)))
+ !s.type.getReturnType().hasTag(VOID)) ||
+ (s.kind == MTH && s.isConstructor()))
+ return true;
+ }
+ else if (target == names.TYPE_PARAMETER)
+ { if (s.kind == TYP && s.type.hasTag(TYPEVAR))
return true;
}
else
@@ -2891,6 +2913,11 @@
return (Attribute.Array) atValue;
}
+ private final Name[] dfltTargetMeta;
+ private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
+ return dfltTargetMeta;
+ }
+
/** Check an annotation value.
*
* @param a The annotation tree to check
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java Sat Jan 26 19:24:46 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
@@ -29,8 +29,6 @@
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.code.Type.*;
-
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
import static com.sun.tools.javac.jvm.ByteCodes.*;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Sat Jan 26 19:24:46 2013 -0800
@@ -65,6 +65,7 @@
final Attr attr;
final Check chk;
+ final JCDiagnostic.Factory diags;
final Enter enter;
final Infer infer;
final Log log;
@@ -83,14 +84,20 @@
context.put(deferredAttrKey, this);
attr = Attr.instance(context);
chk = Check.instance(context);
+ diags = JCDiagnostic.Factory.instance(context);
enter = Enter.instance(context);
infer = Infer.instance(context);
log = Log.instance(context);
syms = Symtab.instance(context);
make = TreeMaker.instance(context);
types = Types.instance(context);
+ Names names = Names.instance(context);
+ stuckTree = make.Ident(names.empty).setType(Type.noType);
}
+ /** shared tree for stuck expressions */
+ final JCTree stuckTree;
+
/**
* This type represents a deferred type. A deferred type starts off with
* no information on the underlying expression type. Such info needs to be
@@ -356,12 +363,11 @@
//scan a defensive copy of the node list - this is because a deferred
//attribution round can add new nodes to the list
for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
- if (!deferredAttrNode.isStuck()) {
- deferredAttrNode.process();
+ if (!deferredAttrNode.process()) {
+ stuckVars.addAll(deferredAttrNode.stuckVars);
+ } else {
deferredAttrNodes.remove(deferredAttrNode);
progress = true;
- } else {
- stuckVars.addAll(deferredAttrNode.stuckVars);
}
}
if (!progress) {
@@ -404,21 +410,88 @@
}
/**
- * is this node stuck?
+ * Process a deferred attribution node.
+ * Invariant: a stuck node cannot be processed.
*/
- boolean isStuck() {
- return stuckVars.nonEmpty();
+ @SuppressWarnings("fallthrough")
+ boolean process() {
+ switch (mode) {
+ case SPECULATIVE:
+ dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
+ return true;
+ case CHECK:
+ if (stuckVars.nonEmpty()) {
+ return false;
+ } else {
+ dt.check(resultInfo, stuckVars, basicCompleter);
+ return true;
+ }
+ default:
+ throw new AssertionError("Bad mode");
+ }
}
/**
- * Process a deferred attribution node.
- * Invariant: a stuck node cannot be processed.
+ * Structural checker for stuck expressions
*/
- void process() {
- if (isStuck()) {
- throw new IllegalStateException("Cannot process a stuck deferred node");
+ class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
+
+ ResultInfo resultInfo;
+
+ public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+ this.resultInfo = resultInfo;
+ dt.tree.accept(this);
+ dt.speculativeCache.put(msym, stuckTree, phase);
+ return Type.noType;
}
- dt.check(resultInfo);
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ Check.CheckContext checkContext = resultInfo.checkContext;
+ Type pt = resultInfo.pt;
+ if (inferenceContext.inferencevars.contains(pt)) {
+ //ok
+ return;
+ } else {
+ //must be a functional descriptor
+ try {
+ Type desc = types.findDescriptorType(pt);
+ if (desc.getParameterTypes().length() != tree.params.length()) {
+ checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
+ }
+ } catch (Types.FunctionDescriptorLookupError ex) {
+ checkContext.report(null, ex.getDiagnostic());
+ }
+ }
+ }
+
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ //do nothing
+ }
+
+ @Override
+ public void visitApply(JCMethodInvocation tree) {
+ //do nothing
+ }
+
+ @Override
+ public void visitReference(JCMemberReference tree) {
+ Check.CheckContext checkContext = resultInfo.checkContext;
+ Type pt = resultInfo.pt;
+ if (inferenceContext.inferencevars.contains(pt)) {
+ //ok
+ return;
+ } else {
+ try {
+ //TODO: we should speculative determine if there's a match
+ //based on arity - if yes, method is applicable.
+ types.findDescriptorType(pt);
+ } catch (Types.FunctionDescriptorLookupError ex) {
+ checkContext.report(null, ex.getDiagnostic());
+ }
+ }
+ }
}
}
}
@@ -624,12 +697,12 @@
if (inferenceContext.inferenceVars().contains(pt)) {
stuckVars.add(pt);
}
- if (!types.isFunctionalInterface(pt.tsym)) {
+ if (!types.isFunctionalInterface(pt)) {
return;
}
Type descType = types.findDescriptorType(pt);
List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
- if (!TreeInfo.isExplicitLambda(tree) &&
+ if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT &&
freeArgVars.nonEmpty()) {
stuckVars.addAll(freeArgVars);
}
@@ -643,7 +716,7 @@
stuckVars.add(pt);
return;
}
- if (!types.isFunctionalInterface(pt.tsym)) {
+ if (!types.isFunctionalInterface(pt)) {
return;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Sat Jan 26 19:24:46 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
@@ -131,7 +131,11 @@
predefClassDef = make.ClassDef(
make.Modifiers(PUBLIC),
- syms.predefClass.name, null, null, null, null);
+ syms.predefClass.name,
+ List.<JCTypeParameter>nil(),
+ null,
+ List.<JCExpression>nil(),
+ List.<JCTree>nil());
predefClassDef.sym = syms.predefClass;
todo = Todo.instance(context);
fileManager = context.get(JavaFileManager.class);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Sat Jan 26 19:24:46 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
@@ -35,6 +35,7 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*;
@@ -2175,6 +2176,11 @@
unrefdResources.remove(sym);
}
+ public void visitAnnotatedType(JCAnnotatedType tree) {
+ // annotations don't get scanned
+ tree.underlyingType.accept(this);
+ }
+
public void visitTopLevel(JCCompilationUnit tree) {
// Do nothing for TopLevel since each class is visited individually
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Sat Jan 26 19:24:46 2013 -0800
@@ -66,6 +66,9 @@
Log log;
JCDiagnostic.Factory diags;
+ /** Should we inject return-type constraints earlier? */
+ boolean allowEarlyReturnConstraints;
+
public static Infer instance(Context context) {
Infer instance = context.get(inferKey);
if (instance == null)
@@ -83,6 +86,7 @@
chk = Check.instance(context);
diags = JCDiagnostic.Factory.instance(context);
inferenceException = new InferenceException(diags);
+ allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints();
}
/**
@@ -188,19 +192,6 @@
MethodType mtype,
Attr.ResultInfo resultInfo,
Warner warn) throws InferenceException {
- Type to = resultInfo.pt;
- if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
- to = mtype.getReturnType().isPrimitiveOrVoid() ?
- mtype.getReturnType() : syms.objectType;
- }
- Type qtype1 = inferenceContext.asFree(mtype.getReturnType(), types);
- if (!types.isSubtype(qtype1,
- qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) {
- throw inferenceException
- .setMessage("infer.no.conforming.instance.exists",
- inferenceContext.restvars(), mtype.getReturnType(), to);
- }
-
while (true) {
boolean stuck = true;
for (Type t : inferenceContext.undetvars) {
@@ -283,6 +274,11 @@
try {
methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
+ if (resultInfo != null && allowEarlyReturnConstraints &&
+ !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+ generateReturnConstraints(mt, inferenceContext, resultInfo);
+ }
+
deferredAttrContext.complete();
// minimize as yet undetermined type variables
@@ -298,6 +294,9 @@
if (!restvars.isEmpty()) {
if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+ if (!allowEarlyReturnConstraints) {
+ generateReturnConstraints(mt, inferenceContext, resultInfo);
+ }
instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
checkWithinBounds(inferenceContext, warn);
mt = (MethodType)inferenceContext.asInstType(mt, types);
@@ -313,6 +312,25 @@
inferenceContext.notifyChange(types);
}
}
+ //where
+ void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) {
+ if (resultInfo != null) {
+ Type to = resultInfo.pt;
+ if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
+ to = mt.getReturnType().isPrimitiveOrVoid() ?
+ mt.getReturnType() : syms.objectType;
+ }
+ Type qtype1 = inferenceContext.asFree(mt.getReturnType(), types);
+ Warner retWarn = new Warner();
+ if (!resultInfo.checkContext.compatible(qtype1, qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to, retWarn) ||
+ //unchecked conversion is not allowed
+ retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
+ throw inferenceException
+ .setMessage("infer.no.conforming.instance.exists",
+ inferenceContext.restvars(), mt.getReturnType(), to);
+ }
+ }
+ }
/** check that type parameters are within their bounds.
*/
@@ -461,52 +479,40 @@
Type formalInterface = funcInterface.tsym.type;
InferenceContext funcInterfaceContext =
new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false);
- if (paramTypes != null) {
- //get constraints from explicit params (this is done by
- //checking that explicit param types are equal to the ones
- //in the functional interface descriptors)
- List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
- if (descParameterTypes.size() != paramTypes.size()) {
- checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+ Assert.check(paramTypes != null);
+ //get constraints from explicit params (this is done by
+ //checking that explicit param types are equal to the ones
+ //in the functional interface descriptors)
+ List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
+ if (descParameterTypes.size() != paramTypes.size()) {
+ checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+ return types.createErrorType(funcInterface);
+ }
+ for (Type p : descParameterTypes) {
+ if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
+ checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
return types.createErrorType(funcInterface);
}
- for (Type p : descParameterTypes) {
- if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
- checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
- return types.createErrorType(funcInterface);
- }
- paramTypes = paramTypes.tail;
+ paramTypes = paramTypes.tail;
+ }
+ List<Type> actualTypeargs = funcInterface.getTypeArguments();
+ for (Type t : funcInterfaceContext.undetvars) {
+ UndetVar uv = (UndetVar)t;
+ minimizeInst(uv, types.noWarnings);
+ if (uv.inst == null &&
+ Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
+ maximizeInst(uv, types.noWarnings);
}
- for (Type t : funcInterfaceContext.undetvars) {
- UndetVar uv = (UndetVar)t;
- minimizeInst(uv, types.noWarnings);
- if (uv.inst == null &&
- Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
- maximizeInst(uv, types.noWarnings);
- }
- }
-
- formalInterface = funcInterfaceContext.asInstType(formalInterface, types);
- }
- ListBuffer<Type> typeargs = ListBuffer.lb();
- List<Type> actualTypeargs = funcInterface.getTypeArguments();
- //for remaining uninferred type-vars in the functional interface type,
- //simply replace the wildcards with its bound
- for (Type t : formalInterface.getTypeArguments()) {
- if (actualTypeargs.head.hasTag(WILDCARD)) {
- WildcardType wt = (WildcardType)actualTypeargs.head;
- typeargs.append(wt.type);
- } else {
- typeargs.append(actualTypeargs.head);
+ if (uv.inst == null) {
+ uv.inst = actualTypeargs.head;
}
actualTypeargs = actualTypeargs.tail;
}
- Type owntype = types.subst(formalInterface, funcInterfaceContext.inferenceVars(), typeargs.toList());
+ Type owntype = funcInterfaceContext.asInstType(formalInterface, types);
if (!chk.checkValidGenericType(owntype)) {
//if the inferred functional interface type is not well-formed,
//or if it's not a subtype of the original target, issue an error
checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
- return types.createErrorType(funcInterface);
}
return owntype;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Sat Jan 26 19:24:46 2013 -0800
@@ -253,7 +253,7 @@
int refKind = referenceKind(sym);
//convert to an invokedynamic call
- result = makeMetaFactoryIndyCall(tree, tree.targetType, refKind, sym, indy_args);
+ result = makeMetaFactoryIndyCall(tree, refKind, sym, indy_args);
}
private JCIdent makeThis(Type type, Symbol owner) {
@@ -302,6 +302,7 @@
case UNBOUND: /** Type :: instMethod */
case STATIC: /** Type :: staticMethod */
case TOPLEVEL: /** Top level :: new */
+ case ARRAY_CTOR: /** ArrayType :: new */
init = null;
break;
@@ -313,7 +314,7 @@
//build a sam instance using an indy call to the meta-factory
- result = makeMetaFactoryIndyCall(tree, tree.targetType, localContext.referenceKind(), refSym, indy_args);
+ result = makeMetaFactoryIndyCall(tree, localContext.referenceKind(), refSym, indy_args);
}
/**
@@ -502,19 +503,6 @@
// </editor-fold>
- private MethodSymbol makeSamDescriptor(Type targetType) {
- return (MethodSymbol)types.findDescriptorSymbol(targetType.tsym);
- }
-
- private Type makeFunctionalDescriptorType(Type targetType, MethodSymbol samDescriptor, boolean erased) {
- Type descType = types.memberType(targetType, samDescriptor);
- return erased ? types.erasure(descType) : descType;
- }
-
- private Type makeFunctionalDescriptorType(Type targetType, boolean erased) {
- return makeFunctionalDescriptorType(targetType, makeSamDescriptor(targetType), erased);
- }
-
/**
* Generate an adapter method "bridge" for a method reference which cannot
* be used directly.
@@ -645,24 +633,33 @@
* to the first bridge synthetic parameter
*/
private JCExpression bridgeExpressionNew() {
- JCExpression encl = null;
- switch (tree.kind) {
- case UNBOUND:
- case IMPLICIT_INNER:
- encl = make.Ident(params.first());
- }
+ if (tree.kind == ReferenceKind.ARRAY_CTOR) {
+ //create the array creation expression
+ JCNewArray newArr = make.NewArray(make.Type(types.elemtype(tree.getQualifierExpression().type)),
+ List.of(make.Ident(params.first())),
+ null);
+ newArr.type = tree.getQualifierExpression().type;
+ return newArr;
+ } else {
+ JCExpression encl = null;
+ switch (tree.kind) {
+ case UNBOUND:
+ case IMPLICIT_INNER:
+ encl = make.Ident(params.first());
+ }
- //create the instance creation expression
- JCNewClass newClass = make.NewClass(encl,
- List.<JCExpression>nil(),
- make.Type(tree.getQualifierExpression().type),
- convertArgs(tree.sym, args.toList(), tree.varargsElement),
- null);
- newClass.constructor = tree.sym;
- newClass.constructorType = tree.sym.erasure(types);
- newClass.type = tree.getQualifierExpression().type;
- setVarargsIfNeeded(newClass, tree.varargsElement);
- return newClass;
+ //create the instance creation expression
+ JCNewClass newClass = make.NewClass(encl,
+ List.<JCExpression>nil(),
+ make.Type(tree.getQualifierExpression().type),
+ convertArgs(tree.sym, args.toList(), tree.varargsElement),
+ null);
+ newClass.constructor = tree.sym;
+ newClass.constructorType = tree.sym.erasure(types);
+ newClass.type = tree.getQualifierExpression().type;
+ setVarargsIfNeeded(newClass, tree.varargsElement);
+ return newClass;
+ }
}
private VarSymbol addParameter(String name, Type p, boolean genArg) {
@@ -688,12 +685,12 @@
/**
* Generate an indy method call to the meta factory
*/
- private JCExpression makeMetaFactoryIndyCall(JCExpression tree, Type targetType, int refKind, Symbol refSym, List<JCExpression> indy_args) {
+ private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, int refKind, Symbol refSym, List<JCExpression> indy_args) {
//determine the static bsm args
- Type mtype = makeFunctionalDescriptorType(targetType, true);
+ Type mtype = types.erasure(tree.descriptorType);
+ MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
List<Object> staticArgs = List.<Object>of(
- new Pool.MethodHandle(ClassFile.REF_invokeInterface,
- types.findDescriptorSymbol(targetType.tsym), types),
+ new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(tree.type.tsym), types),
new Pool.MethodHandle(refKind, refSym, types),
new MethodType(mtype.getParameterTypes(),
mtype.getReturnType(),
@@ -862,8 +859,8 @@
finally {
frameStack = prevStack;
}
- if (frameStack.nonEmpty() && enclosingLambda() != null) {
- // Any class defined within a lambda is an implicit 'this' reference
+ if (!tree.sym.isStatic() && frameStack.nonEmpty() && enclosingLambda() != null) {
+ // Any (non-static) class defined within a lambda is an implicit 'this' reference
// because its constructor will reference the enclosing class
((LambdaTranslationContext) context()).addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
}
@@ -997,6 +994,11 @@
* (required to skip synthetic lambda symbols)
*/
private Symbol owner() {
+ return owner(false);
+ }
+
+ @SuppressWarnings("fallthrough")
+ private Symbol owner(boolean skipLambda) {
List<Frame> frameStack2 = frameStack;
while (frameStack2.nonEmpty()) {
switch (frameStack2.head.tree.getTag()) {
@@ -1015,7 +1017,8 @@
case METHODDEF:
return ((JCMethodDecl)frameStack2.head.tree).sym;
case LAMBDA:
- return ((LambdaTranslationContext)contextMap.get(frameStack2.head.tree)).translatedSym;
+ if (!skipLambda)
+ return ((LambdaTranslationContext)contextMap.get(frameStack2.head.tree)).translatedSym;
default:
frameStack2 = frameStack2.tail;
}
@@ -1155,7 +1158,7 @@
* This class is used to store important information regarding translation of
* lambda expression/method references (see subclasses).
*/
- private abstract class TranslationContext<T extends JCTree> {
+ private abstract class TranslationContext<T extends JCFunctionalExpression> {
/** the underlying (untranslated) tree */
T tree;
@@ -1314,12 +1317,13 @@
}
Type enclosingType() {
- //local inner classes defined inside a lambda are always non-static
- return owner.enclClass().type;
+ return owner.isStatic() ?
+ Type.noType :
+ owner.enclClass().type;
}
Type generatedLambdaSig() {
- return types.erasure(types.findDescriptorType(tree.targetType));
+ return types.erasure(tree.descriptorType);
}
}
@@ -1375,7 +1379,7 @@
}
Type bridgedRefSig() {
- return types.erasure(types.findDescriptorSymbol(tree.targetType.tsym).type);
+ return types.erasure(types.findDescriptorSymbol(tree.targets.head).type);
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Sat Jan 26 19:24:46 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
@@ -2288,7 +2288,7 @@
return tree.packageAnnotations.nonEmpty();
case NONEMPTY:
for (Attribute.Compound a :
- tree.packge.annotations.getAttributes()) {
+ tree.packge.annotations.getDeclarationAttributes()) {
Attribute.RetentionPolicy p = types.getRetention(a);
if (p != Attribute.RetentionPolicy.SOURCE)
return true;
@@ -2685,6 +2685,13 @@
result = tree;
}
+ public void visitAnnotatedType(JCAnnotatedType tree) {
+ // No need to retain type annotations any longer.
+ // tree.annotations = translate(tree.annotations);
+ tree.underlyingType = translate(tree.underlyingType);
+ result = tree.underlyingType;
+ }
+
public void visitTypeCast(JCTypeCast tree) {
tree.clazz = translate(tree.clazz);
if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sat Jan 26 19:24:46 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,15 +25,19 @@
package com.sun.tools.javac.comp;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Set;
+
+import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Symbol.*;
@@ -345,12 +349,15 @@
* @param params The method's value parameters.
* @param res The method's result type,
* null if it is a constructor.
+ * @param recvparam The method's receiver parameter,
+ * null if none given; TODO: or already set here?
* @param thrown The method's thrown exceptions.
* @param env The method's (local) environment.
*/
Type signature(List<JCTypeParameter> typarams,
List<JCVariableDecl> params,
JCTree res,
+ JCVariableDecl recvparam,
List<JCExpression> thrown,
Env<AttrContext> 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<Type> thrownbuf = new ListBuffer<Type>();
for (List<JCExpression> 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<JCAnnotation> annotations,
+ private void actualEnterAnnotations(List<JCAnnotation> annotations,
Env<AttrContext> env,
Symbol s) {
Map<TypeSymbol, ListBuffer<Attribute.Compound>> 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<Attribute.Compound>(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<AttrContext> 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<JCAnnotation> annotations,
+ final Env<AttrContext> env,
+ final Symbol s) {
+ Map<TypeSymbol, ListBuffer<Attribute.TypeCompound>> annotated =
+ new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.TypeCompound>>();
+ Map<Attribute.TypeCompound, DiagnosticPosition> pos =
+ new HashMap<Attribute.TypeCompound, DiagnosticPosition>();
+
+ for (List<JCAnnotation> 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<Attribute.TypeCompound> 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<Attribute.TypeCompound>(env, annotated, pos, log, true));
+ }
+
+ public void typeAnnotate(final JCTree tree, final Env<AttrContext> 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<AttrContext> env;
+ private Symbol sym;
+
+ public TypeAnnotate(final Env<AttrContext> env, final Symbol sym) {
+ this.env = env;
+ this.sym = sym;
+ }
+
+ void annotateTypeLater(final List<JCAnnotation> 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<JCAnnotation> 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<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
Scope baseScope = new Scope(tree.sym);
//import already entered local classes into base scope
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Jan 26 19:24:46 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
@@ -41,6 +41,7 @@
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -54,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;
@@ -92,6 +92,7 @@
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
public final boolean allowDefaultMethods;
+ public final boolean allowStructuralMostSpecific;
private final boolean debugResolve;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
@@ -127,6 +128,7 @@
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
allowDefaultMethods = source.allowDefaultMethods();
+ allowStructuralMostSpecific = source.allowStructuralMostSpecific();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@@ -693,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) {
@@ -704,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) {
@@ -721,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;
@@ -745,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);
}
}
}
@@ -758,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);
@@ -835,6 +837,213 @@
}
}
+ /**
+ * Most specific method applicability routine. Given a list of actual types A,
+ * a list of formal types F1, and a list of formal types F2, the routine determines
+ * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
+ * argument types A.
+ */
+ class MostSpecificCheck implements MethodCheck {
+
+ boolean strict;
+ List<Type> actuals;
+
+ MostSpecificCheck(boolean strict, List<Type> actuals) {
+ this.strict = strict;
+ this.actuals = actuals;
+ }
+
+ @Override
+ public void argumentsAcceptable(final Env<AttrContext> env,
+ DeferredAttrContext deferredAttrContext,
+ List<Type> formals1,
+ List<Type> formals2,
+ Warner warn) {
+ formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
+ while (formals2.nonEmpty()) {
+ ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
+ mresult.check(null, formals1.head);
+ formals1 = formals1.tail;
+ formals2 = formals2.tail;
+ actuals = actuals.isEmpty() ? actuals : actuals.tail;
+ }
+ }
+
+ /**
+ * Create a method check context to be used during the most specific applicability check
+ */
+ ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
+ Warner rsWarner, Type actual) {
+ return attr.new ResultInfo(Kinds.VAL, to,
+ new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual));
+ }
+
+ /**
+ * Subclass of method check context class that implements most specific
+ * method conversion. If the actual type under analysis is a deferred type
+ * a full blown structural analysis is carried out.
+ */
+ class MostSpecificCheckContext extends MethodCheckContext {
+
+ Type actual;
+
+ public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
+ super(strict, deferredAttrContext, rsWarner);
+ this.actual = actual;
+ }
+
+ public boolean compatible(Type found, Type req, Warner warn) {
+ if (!allowStructuralMostSpecific || actual == null) {
+ return super.compatible(found, req, warn);
+ } else {
+ switch (actual.getTag()) {
+ case DEFERRED:
+ DeferredType dt = (DeferredType) actual;
+ DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
+ return (e == null || e.speculativeTree == deferredAttr.stuckTree)
+ ? false : mostSpecific(found, req, e.speculativeTree, warn);
+ default:
+ return standaloneMostSpecific(found, req, actual, warn);
+ }
+ }
+ }
+
+ private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) {
+ MostSpecificChecker msc = new MostSpecificChecker(t, s, warn);
+ msc.scan(tree);
+ return msc.result;
+ }
+
+ boolean polyMostSpecific(Type t1, Type t2, Warner warn) {
+ return (!t1.isPrimitive() && t2.isPrimitive())
+ ? true : super.compatible(t1, t2, warn);
+ }
+
+ boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) {
+ return (exprType.isPrimitive() == t1.isPrimitive()
+ && exprType.isPrimitive() != t2.isPrimitive())
+ ? true : super.compatible(t1, t2, warn);
+ }
+
+ /**
+ * Structural checker for most specific.
+ */
+ class MostSpecificChecker extends DeferredAttr.PolyScanner {
+
+ final Type t;
+ final Type s;
+ final Warner warn;
+ boolean result;
+
+ MostSpecificChecker(Type t, Type s, Warner warn) {
+ this.t = t;
+ this.s = s;
+ this.warn = warn;
+ result = true;
+ }
+
+ @Override
+ void skip(JCTree tree) {
+ result &= standaloneMostSpecific(t, s, tree.type, warn);
+ }
+
+ @Override
+ public void visitConditional(JCConditional tree) {
+ if (tree.polyKind == PolyKind.STANDALONE) {
+ result &= standaloneMostSpecific(t, s, tree.type, warn);
+ } else {
+ super.visitConditional(tree);
+ }
+ }
+
+ @Override
+ public void visitApply(JCMethodInvocation tree) {
+ result &= (tree.polyKind == PolyKind.STANDALONE)
+ ? standaloneMostSpecific(t, s, tree.type, warn)
+ : polyMostSpecific(t, s, warn);
+ }
+
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ result &= (tree.polyKind == PolyKind.STANDALONE)
+ ? standaloneMostSpecific(t, s, tree.type, warn)
+ : polyMostSpecific(t, s, warn);
+ }
+
+ @Override
+ public void visitReference(JCMemberReference tree) {
+ if (types.isFunctionalInterface(t.tsym) &&
+ types.isFunctionalInterface(s.tsym) &&
+ types.asSuper(t, s.tsym) == null &&
+ types.asSuper(s, t.tsym) == null) {
+ Type desc_t = types.findDescriptorType(t);
+ Type desc_s = types.findDescriptorType(s);
+ if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
+ if (!desc_s.getReturnType().hasTag(VOID)) {
+ //perform structural comparison
+ Type ret_t = desc_t.getReturnType();
+ Type ret_s = desc_s.getReturnType();
+ result &= ((tree.refPolyKind == PolyKind.STANDALONE)
+ ? standaloneMostSpecific(ret_t, ret_s, tree.type, warn)
+ : polyMostSpecific(ret_t, ret_s, warn));
+ } else {
+ return;
+ }
+ } else {
+ result &= false;
+ }
+ } else {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ }
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (types.isFunctionalInterface(t.tsym) &&
+ types.isFunctionalInterface(s.tsym) &&
+ types.asSuper(t, s.tsym) == null &&
+ types.asSuper(s, t.tsym) == null) {
+ Type desc_t = types.findDescriptorType(t);
+ Type desc_s = types.findDescriptorType(s);
+ if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
+ || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
+ if (!desc_s.getReturnType().hasTag(VOID)) {
+ //perform structural comparison
+ Type ret_t = desc_t.getReturnType();
+ Type ret_s = desc_s.getReturnType();
+ scanLambdaBody(tree, ret_t, ret_s);
+ } else {
+ return;
+ }
+ } else {
+ result &= false;
+ }
+ } else {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ }
+ }
+ //where
+
+ void scanLambdaBody(JCLambda lambda, final Type t, final Type s) {
+ if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
+ result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn);
+ } else {
+ DeferredAttr.LambdaReturnScanner lambdaScanner =
+ new DeferredAttr.LambdaReturnScanner() {
+ @Override
+ public void visitReturn(JCReturn tree) {
+ if (tree.expr != null) {
+ result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn);
+ }
+ }
+ };
+ lambdaScanner.scan(lambda.body);
+ }
+ }
+ }
+ }
+ }
+
public static class InapplicableMethodException extends RuntimeException {
private static final long serialVersionUID = 0;
@@ -1142,153 +1351,32 @@
}
//where
private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
- Symbol m12 = adjustVarargs(m1, m2, useVarargs);
- Symbol m22 = adjustVarargs(m2, m1, useVarargs);
- Type mtype1 = types.memberType(site, m12);
- Type mtype2 = types.memberType(site, m22);
-
- //check if invocation is more specific
- if (invocationMoreSpecific(env, site, m22, mtype1.getParameterTypes(), allowBoxing, useVarargs)) {
- return true;
- }
-
- //perform structural check
-
- List<Type> formals1 = mtype1.getParameterTypes();
- Type lastFormal1 = formals1.last();
- List<Type> formals2 = mtype2.getParameterTypes();
- Type lastFormal2 = formals2.last();
- ListBuffer<Type> newFormals = ListBuffer.lb();
-
- boolean hasStructuralPoly = false;
- for (Type actual : actuals) {
- //perform formal argument adaptation in case actuals > formals (varargs)
- Type f1 = formals1.isEmpty() ?
- lastFormal1 : formals1.head;
- Type f2 = formals2.isEmpty() ?
- lastFormal2 : formals2.head;
-
- //is this a structural actual argument?
- boolean isStructuralPoly = actual.hasTag(DEFERRED) &&
- (((DeferredType)actual).tree.hasTag(LAMBDA) ||
- ((DeferredType)actual).tree.hasTag(REFERENCE));
-
- Type newFormal = f1;
-
- if (isStructuralPoly) {
- //for structural arguments only - check that corresponding formals
- //are related - if so replace formal with <null>
- hasStructuralPoly = true;
- DeferredType dt = (DeferredType)actual;
- Type t1 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m1, currentResolutionContext.step).apply(dt);
- Type t2 = deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, m2, currentResolutionContext.step).apply(dt);
- if (t1.isErroneous() || t2.isErroneous() || !isStructuralSubtype(t1, t2)) {
- //not structural subtypes - simply fail
- return false;
- } else {
- newFormal = syms.botType;
- }
- }
-
- newFormals.append(newFormal);
- if (newFormals.length() > mtype2.getParameterTypes().length()) {
- //expand m2's type so as to fit the new formal arity (varargs)
- m22.type = types.createMethodTypeWithParameters(m22.type, m22.type.getParameterTypes().append(f2));
- }
-
- formals1 = formals1.isEmpty() ? formals1 : formals1.tail;
- formals2 = formals2.isEmpty() ? formals2 : formals2.tail;
- }
-
- if (!hasStructuralPoly) {
- //if no structural actual was found, we're done
- return false;
- }
- //perform additional adaptation if actuals < formals (varargs)
- for (Type t : formals1) {
- newFormals.append(t);
- }
- //check if invocation (with tweaked args) is more specific
- return invocationMoreSpecific(env, site, m22, newFormals.toList(), allowBoxing, useVarargs);
+ noteWarner.clear();
+ int maxLength = Math.max(
+ Math.max(m1.type.getParameterTypes().length(), actuals.length()),
+ m2.type.getParameterTypes().length());
+ Type mst = instantiate(env, site, m2, null,
+ adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
+ allowBoxing, useVarargs, new MostSpecificCheck(!allowBoxing, actuals), noteWarner);
+ return mst != null &&
+ !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
}
- //where
- private boolean invocationMoreSpecific(Env<AttrContext> env, Type site, Symbol m2, List<Type> argtypes1, boolean allowBoxing, boolean useVarargs) {
- MethodResolutionContext prevContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- currentResolutionContext.step = allowBoxing ? BOX : BASIC;
- noteWarner.clear();
- Type mst = instantiate(env, site, m2, null,
- types.lowerBounds(argtypes1), null,
- allowBoxing, false, resolveMethodCheck, noteWarner);
- return mst != null &&
- !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
- } finally {
- currentResolutionContext = prevContext;
+ private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
+ if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
+ Type varargsElem = types.elemtype(args.last());
+ if (varargsElem == null) {
+ Assert.error("Bad varargs = " + args.last() + " " + msym);
+ }
+ List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
+ while (newArgs.length() < length) {
+ newArgs = newArgs.append(newArgs.last());
+ }
+ return newArgs;
+ } else {
+ return args;
}
}
//where
- private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
- List<Type> fromArgs = from.type.getParameterTypes();
- List<Type> toArgs = to.type.getParameterTypes();
- if (useVarargs &&
- (from.flags() & VARARGS) != 0 &&
- (to.flags() & VARARGS) != 0) {
- Type varargsTypeFrom = fromArgs.last();
- Type varargsTypeTo = toArgs.last();
- ListBuffer<Type> args = ListBuffer.lb();
- if (toArgs.length() < fromArgs.length()) {
- //if we are checking a varargs method 'from' against another varargs
- //method 'to' (where arity of 'to' < arity of 'from') then expand signature
- //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
- //until 'to' signature has the same arity as 'from')
- while (fromArgs.head != varargsTypeFrom) {
- args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
- fromArgs = fromArgs.tail;
- toArgs = toArgs.head == varargsTypeTo ?
- toArgs :
- toArgs.tail;
- }
- } else {
- //formal argument list is same as original list where last
- //argument (array type) is removed
- args.appendList(toArgs.reverse().tail.reverse());
- }
- //append varargs element type as last synthetic formal
- args.append(types.elemtype(varargsTypeTo));
- Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
- return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
- } else {
- return to;
- }
- }
- //where
- boolean isStructuralSubtype(Type s, Type t) {
-
- Type ret_s = types.findDescriptorType(s).getReturnType();
- Type ret_t = types.findDescriptorType(t).getReturnType();
-
- //covariant most specific check for function descriptor return type
- if (!types.isSubtype(ret_s, ret_t)) {
- return false;
- }
-
- List<Type> args_s = types.findDescriptorType(s).getParameterTypes();
- List<Type> args_t = types.findDescriptorType(t).getParameterTypes();
-
- //arity must be identical
- if (args_s.length() != args_t.length()) {
- return false;
- }
-
- //invariant most specific check for function descriptor parameter types
- if (!types.isSameTypes(args_t, args_s)) {
- return false;
- }
-
- return true;
- }
- //where
Type mostSpecificReturnType(Type mt1, Type mt2) {
Type rt1 = mt1.getReturnType();
Type rt2 = mt2.getReturnType();
@@ -2386,10 +2474,23 @@
List<Type> typeargtypes,
boolean boxingAllowed) {
MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
+
+ ReferenceLookupHelper boundLookupHelper;
+ if (!name.equals(names.init)) {
+ //method reference
+ boundLookupHelper =
+ new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ } else if (site.hasTag(ARRAY)) {
+ //array constructor reference
+ boundLookupHelper =
+ new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+ } else {
+ //class constructor reference
+ boundLookupHelper =
+ new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+ }
+
//step 1 - bound lookup
- ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
- new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) :
- new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
@@ -2627,6 +2728,33 @@
}
/**
+ * Helper class for array constructor lookup; an array constructor lookup
+ * is simulated by looking up a method that returns the array type specified
+ * as qualifier, and that accepts a single int parameter (size of the array).
+ */
+ class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
+
+ ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
+ List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
+ }
+
+ @Override
+ protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ Scope sc = new Scope(syms.arrayClass);
+ MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
+ arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
+ sc.enter(arrayConstr);
+ return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return ReferenceKind.ARRAY_CTOR;
+ }
+ }
+
+ /**
* Helper class for constructor reference lookup. The lookup logic is based
* upon either Resolve.findMethod or Resolve.findDiamond - depending on
* whether the constructor reference needs diamond inference (this is the case
@@ -3381,7 +3509,10 @@
@Override
protected Symbol access(Name name, TypeSymbol location) {
- return ambiguousSyms.last();
+ Symbol firstAmbiguity = ambiguousSyms.last();
+ return firstAmbiguity.kind == TYP ?
+ types.createErrorType(name, location, firstAmbiguity.type).tsym :
+ firstAmbiguity;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Sat Jan 26 19:24:46 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);
@@ -549,9 +550,6 @@
currentMethod = null;
tree.params = translate(tree.params);
tree.body = translate(tree.body, null);
- //save non-erased target
- tree.targetType = tree.type;
- Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
tree.type = erasure(tree.type);
result = tree;
}
@@ -785,9 +783,6 @@
public void visitReference(JCMemberReference tree) {
tree.expr = translate(tree.expr, null);
- //save non-erased target
- tree.targetType = tree.type;
- Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
tree.type = erasure(tree.type);
result = tree;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Sat Jan 26 19:24:46 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<TypeAnnotationProxy> 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<Integer> 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<Attribute.Compound> 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<TypeAnnotationProxy> proxies;
+
+ TypeAnnotationCompleter(Symbol sym,
+ List<TypeAnnotationProxy> proxies) {
+ super(sym, List.<CompoundAnnotationProxy>nil());
+ this.proxies = proxies;
+ }
+
+ List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
+ ListBuffer<Attribute.TypeCompound> 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<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
+ sym.annotations.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes()));
+ } finally {
+ currentClassFile = previousClassFile;
+ }
+ }
+ }
+
/************************************************************************
* Reading Symbols
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Sat Jan 26 19:24:46 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<ClassWriter> classWriterKey =
new Context.Key<ClassWriter>();
- 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<Attribute.TypeCompound> typeAnnos) {
+ if (typeAnnos.isEmpty()) return 0;
+
+ ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
+ ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
+
+ for (Attribute.TypeCompound tc : typeAnnos) {
+ if (tc.position == null || tc.position.type == TargetType.UNKNOWN) {
+ boolean found = false;
+ // TODO: the position for the container annotation of a
+ // repeating type annotation has to be set.
+ // This cannot be done when the container is created, because
+ // then the position is not determined yet.
+ // How can we link these pieces better together?
+ if (tc.values.size() == 1) {
+ Pair<MethodSymbol, Attribute> val = tc.values.get(0);
+ if (val.fst.getSimpleName().contentEquals("value") &&
+ val.snd instanceof Attribute.Array) {
+ Attribute.Array arr = (Attribute.Array) val.snd;
+ if (arr.values.length != 0 &&
+ arr.values[0] instanceof Attribute.TypeCompound) {
+ TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
+ if (atycomp.position.type != TargetType.UNKNOWN) {
+ tc.position = atycomp.position;
+ found = true;
+ }
+ }
+ }
+ }
+ if (!found) {
+ // 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<Integer> 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);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Sat Jan 26 19:24:46 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<char[]> iter = catchInfo.toList();
+ int len = catchInfo.length();
+ for (int i = 0; i < len; ++i) {
+ char[] catchEntry = iter.head;
+ iter = iter.tail;
+ char handlerpc = catchEntry[2];
+ if (lv.start_pc == handlerpc + 1) {
+ 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];
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Sat Jan 26 19:24:46 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);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Sat Jan 26 19:24:46 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;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Sat Jan 26 19:24:46 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;
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Sat Jan 26 19:24:46 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
@@ -27,6 +27,8 @@
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Map;
import javax.lang.model.SourceVersion;
@@ -96,32 +98,43 @@
enter = Enter.instance(context);
}
-
/**
- * An internal-use utility that creates a reified annotation.
+ * An internal-use utility that creates a runtime view of an
+ * annotation. This is the implementation of
+ * Element.getAnnotation(Class).
*/
public static <A extends Annotation> A getAnnotation(Symbol annotated,
Class<A> annoType) {
if (!annoType.isAnnotation())
throw new IllegalArgumentException("Not an annotation type: "
+ annoType);
- String name = annoType.getName();
- for (Attribute.Compound anno : annotated.getAnnotationMirrors())
- if (name.equals(anno.type.tsym.flatName().toString()))
- return AnnotationProxyMaker.generateAnnotation(anno, annoType);
- return null;
+ Attribute.Compound c;
+ if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
+ c = getAttributeOnClass((ClassSymbol)annotated, annoType);
+ } else {
+ c = getAttribute(annotated, annoType);
+ }
+ return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
}
- /**
- * An internal-use utility that creates a reified annotation.
- * This overloaded version take annotation inheritance into account.
- */
- public static <A extends Annotation> A getAnnotation(ClassSymbol annotated,
- Class<A> annoType) {
+ // Helper to getAnnotation[s]
+ private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
+ Class<A> annoType) {
+ String name = annoType.getName();
+
+ for (Attribute.Compound anno : annotated.getRawAttributes())
+ if (name.equals(anno.type.tsym.flatName().toString()))
+ return anno;
+
+ return null;
+ }
+ // Helper to getAnnotation[s]
+ private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
+ Class<A> annoType) {
boolean inherited = annoType.isAnnotationPresent(Inherited.class);
- A result = null;
+ Attribute.Compound result = null;
while (annotated.name != annotated.name.table.names.java_lang_Object) {
- result = getAnnotation((Symbol)annotated, annoType);
+ result = getAttribute(annotated, annoType);
if (result != null || !inherited)
break;
Type sup = annotated.getSuperclass();
@@ -132,6 +145,189 @@
return result;
}
+ /**
+ * An internal-use utility that creates a runtime view of
+ * annotations. This is the implementation of
+ * Element.getAnnotations(Class).
+ */
+ public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
+ Class<A> annoType) {
+ if (!annoType.isAnnotation())
+ throw new IllegalArgumentException("Not an annotation type: "
+ + annoType);
+ // If annoType does not declare a container this is equivalent to wrapping
+ // getAnnotation(...) in an array.
+ Class <? extends Annotation> containerType = getContainer(annoType);
+ if (containerType == null) {
+ A res = getAnnotation(annotated, annoType);
+ int size;
+ if (res == null) {
+ size = 0;
+ } else {
+ size = 1;
+ }
+ @SuppressWarnings("unchecked") // annoType is the Class for A
+ A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+ if (res != null)
+ arr[0] = res;
+ return arr;
+ }
+
+ // So we have a containing type
+ String name = annoType.getName();
+ String annoTypeName = annoType.getSimpleName();
+ String containerTypeName = containerType.getSimpleName();
+ int directIndex = -1, containerIndex = -1;
+ Attribute.Compound direct = null, container = null;
+ Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
+
+ // Find directly present annotations
+ for (int i = 0; i < rawAttributes.length; i++) {
+ if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+ directIndex = i;
+ direct = rawAttributes[i];
+ } else if(containerTypeName != null &&
+ containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+ containerIndex = i;
+ container = rawAttributes[i];
+ }
+ }
+ // Deal with inherited annotations
+ if (annotated.kind == Kinds.TYP &&
+ (annotated instanceof ClassSymbol)) {
+ ClassSymbol s = (ClassSymbol)annotated;
+ if (direct == null && container == null) {
+ direct = getAttributeOnClass(s, annoType);
+ container = getAttributeOnClass(s, containerType);
+
+ // both are inherited and found, put container last
+ if (direct != null && container != null) {
+ directIndex = 0;
+ containerIndex = 1;
+ } else if (direct != null) {
+ directIndex = 0;
+ } else {
+ containerIndex = 0;
+ }
+ } else if (direct == null) {
+ direct = getAttributeOnClass(s, annoType);
+ if (direct != null)
+ directIndex = containerIndex + 1;
+ } else if (container == null) {
+ container = getAttributeOnClass(s, containerType);
+ if (container != null)
+ containerIndex = directIndex + 1;
+ }
+ }
+
+ // Pack them in an array
+ Attribute[] contained0 = new Attribute[0];
+ if (container != null)
+ contained0 = unpackAttributes(container);
+ ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
+ for (Attribute a : contained0)
+ if (a instanceof Attribute.Compound)
+ compounds = compounds.append((Attribute.Compound)a);
+ Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
+
+ int size = (direct == null ? 0 : 1) + contained.length;
+ @SuppressWarnings("unchecked") // annoType is the Class for A
+ A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+
+ // if direct && container, which is first?
+ int insert = -1;
+ int length = arr.length;
+ if (directIndex >= 0 && containerIndex >= 0) {
+ if (directIndex < containerIndex) {
+ arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ insert = 1;
+ } else {
+ arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ insert = 0;
+ length--;
+ }
+ } else if (directIndex >= 0) {
+ arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ return arr;
+ } else {
+ // Only container
+ insert = 0;
+ }
+
+ for (int i = 0; i + insert < length; i++)
+ arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
+
+ return arr;
+ }
+
+ // Needed to unpack the runtime view of containing annotations
+ private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
+ private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
+
+ private static Class<? extends Annotation> initRepeatable() {
+ try {
+ // Repeatable will not be available when bootstrapping on
+ // JDK 7 so use a reflective lookup instead of a class
+ // literal for Repeatable.class.
+ return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
+ } catch (ClassNotFoundException e) {
+ return null;
+ } catch (SecurityException e) {
+ return null;
+ }
+ }
+ private static Method initValueElementMethod() {
+ if (REPEATABLE_CLASS == null)
+ return null;
+
+ Method m = null;
+ try {
+ m = REPEATABLE_CLASS.getMethod("value");
+ if (m != null)
+ m.setAccessible(true);
+ return m;
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ // Helper to getAnnotations
+ private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
+ // Since we can not refer to java.lang.annotation.Repeatable until we are
+ // bootstrapping with java 8 we need to get the Repeatable annotation using
+ // reflective invocations instead of just using its type and element method.
+ if (REPEATABLE_CLASS != null &&
+ VALUE_ELEMENT_METHOD != null) {
+ // Get the Repeatable instance on the annotations declaration
+ Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
+ if (repeatable != null) {
+ try {
+ // Get the value element, it should be a class
+ // indicating the containing annotation type
+ @SuppressWarnings("unchecked")
+ Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
+ if (containerType == null)
+ return null;
+
+ return containerType;
+ } catch (ClassCastException e) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InvocationTargetException e ) {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+ // Helper to getAnnotations
+ private static Attribute[] unpackAttributes(Attribute.Compound container) {
+ // We now have an instance of the container,
+ // unpack it returning an instance of the
+ // contained type or null
+ return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
+ }
public PackageSymbol getPackageElement(CharSequence name) {
String strName = name.toString();
@@ -238,8 +434,10 @@
tree.accept(vis);
if (vis.result == null)
return null;
+
+ List<Attribute.Compound> annos = sym.getRawAttributes();
return matchAnnoToTree(cast(Attribute.Compound.class, findme),
- sym.getAnnotationMirrors(),
+ annos,
vis.result);
}
@@ -442,7 +640,7 @@
*/
public List<Attribute.Compound> getAllAnnotationMirrors(Element e) {
Symbol sym = cast(Symbol.class, e);
- List<Attribute.Compound> annos = sym.getAnnotationMirrors();
+ List<Attribute.Compound> annos = sym.getRawAttributes();
while (sym.getKind() == ElementKind.CLASS) {
Type sup = ((ClassSymbol) sym).getSuperclass();
if (!sup.hasTag(CLASS) || sup.isErroneous() ||
@@ -451,7 +649,8 @@
}
sym = sup.tsym;
List<Attribute.Compound> oldAnnos = annos;
- for (Attribute.Compound anno : sym.getAnnotationMirrors()) {
+ List<Attribute.Compound> newAnnos = sym.getRawAttributes();
+ for (Attribute.Compound anno : newAnnos) {
if (isInherited(anno.type) &&
!containsAnnoOfType(oldAnnos, anno.type)) {
annos = annos.prepend(anno);
@@ -465,11 +664,7 @@
* Tests whether an annotation type is @Inherited.
*/
private boolean isInherited(Type annotype) {
- for (Attribute.Compound anno : annotype.tsym.getAnnotationMirrors()) {
- if (anno.type.tsym == syms.inheritedType.tsym)
- return true;
- }
- return false;
+ return annotype.tsym.attribute(syms.inheritedType.tsym) != null;
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Sat Jan 26 19:24:46 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<? extends AnnotationMirror> typeAnnotationsOf(TypeMirror type) {
+ // TODO: these methods can be removed.
+ return null; // ((Type)type).typeAnnotations;
+ }
+
+ public <A extends Annotation> A typeAnnotationOf(TypeMirror type,
+ Class<A> 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 extends Annotation> A receiverTypeAnnotationOf(
+ ExecutableType type, Class<A> annotationType) {
+ return JavacElements.getAnnotation(
+ ((Type)type).asMethodType().receiverTypeAnnotations,
+ annotationType);
+ }*/
+
}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Sat Jan 26 19:24:46 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<JCAnnotation> 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);
}
@@ -124,9 +159,9 @@
this.allowLambda = source.allowLambda();
this.allowMethodReferences = source.allowMethodReferences();
this.allowDefaultMethods = source.allowDefaultMethods();
- this.allowIntersectionTypesInCast =
- source.allowIntersectionTypesInCast() &&
- fac.options.isSet("allowIntersectionTypes");
+ this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
+ this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
+ this.allowTypeAnnotations = source.allowTypeAnnotations();
this.keepDocComments = keepDocComments;
docComments = newDocCommentTable(keepDocComments, fac);
this.keepLineMap = keepLineMap;
@@ -200,6 +235,10 @@
*/
boolean allowDefaultMethods;
+ /** Switch: should we allow static methods in interfaces?
+ */
+ boolean allowStaticInterfaceMethods;
+
/** Switch: should we allow intersection types in cast?
*/
boolean allowIntersectionTypesInCast;
@@ -212,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
@@ -245,40 +298,42 @@
token = S.token();
}
- protected boolean peekToken(TokenKind tk) {
+ protected boolean peekToken(Filter<TokenKind> tk) {
return peekToken(0, tk);
}
- protected boolean peekToken(int lookahead, TokenKind tk) {
- return S.token(lookahead + 1).kind == tk;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
+ return tk.accepts(S.token(lookahead + 1).kind);
}
- protected boolean peekToken(TokenKind tk1, TokenKind tk2) {
+ protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
return peekToken(0, tk1, tk2);
}
- protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) {
- return S.token(lookahead + 1).kind == tk1 &&
- S.token(lookahead + 2).kind == tk2;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
+ return tk1.accepts(S.token(lookahead + 1).kind) &&
+ tk2.accepts(S.token(lookahead + 2).kind);
}
- protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) {
+ protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
return peekToken(0, tk1, tk2, tk3);
}
- protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) {
- return S.token(lookahead + 1).kind == tk1 &&
- S.token(lookahead + 2).kind == tk2 &&
- S.token(lookahead + 3).kind == tk3;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
+ return tk1.accepts(S.token(lookahead + 1).kind) &&
+ tk2.accepts(S.token(lookahead + 2).kind) &&
+ tk3.accepts(S.token(lookahead + 3).kind);
}
- protected boolean peekToken(TokenKind... kinds) {
+ @SuppressWarnings("unchecked")
+ protected boolean peekToken(Filter<TokenKind>... kinds) {
return peekToken(0, kinds);
}
- protected boolean peekToken(int lookahead, TokenKind... kinds) {
+ @SuppressWarnings("unchecked")
+ protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
for (; lookahead < kinds.length ; lookahead++) {
- if (S.token(lookahead + 1).kind != kinds[lookahead]) {
+ if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
return false;
}
}
@@ -333,6 +388,7 @@
if (stopAtMemberDecl)
return;
break;
+ case UNDERSCORE:
case IDENTIFIER:
if (stopAtIdentifier)
return;
@@ -552,21 +608,45 @@
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();
+ nextToken();
+ return name;
} else {
accept(IDENTIFIER);
return names.error;
}
-}
+ }
/**
- * 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<JCAnnotation> 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;
}
@@ -675,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);
@@ -695,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.
+ *
+ * <p>
+ *
+ * Note that this method sets {@code mode} to {@code TYPE} first, before
+ * parsing annotations.
+ */
public JCExpression parseType() {
+ List<JCAnnotation> annotations = typeAnnotationsOpt();
+ return parseType(annotations);
+ }
+
+ public JCExpression parseType(List<JCAnnotation> annotations) {
+ JCExpression result = unannotatedType();
+
+ if (annotations.nonEmpty()) {
+ result = insertAnnotationsToMostInner(result, annotations, false);
+ }
+
+ return result;
+ }
+
+ public JCExpression unannotatedType() {
return term(TYPE);
}
@@ -853,7 +960,7 @@
opStackSupply.add(opStack);
return t;
}
-//where
+ //where
/** Construct a binary or type test node.
*/
private JCExpression makeOp(int pos,
@@ -932,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 )
* ]
@@ -1056,7 +1163,35 @@
typeArgs = null;
} else return illegal();
break;
- case IDENTIFIER: case ASSERT: case ENUM:
+ case MONKEYS_AT:
+ // Only annotated cast types are valid
+ List<JCAnnotation> 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)) {
t = lambdaExpressionOrStatement(false, false, pos);
@@ -1064,6 +1199,13 @@
t = toP(F.at(token.pos).Ident(ident()));
loop: while (true) {
pos = token.pos;
+ final List<JCAnnotation> 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();
@@ -1071,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);
@@ -1085,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;
@@ -1125,9 +1280,25 @@
break loop;
}
}
+
+ List<JCAnnotation> 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
@@ -1201,6 +1372,8 @@
if (typeArgs != null) illegal();
while (true) {
int pos1 = token.pos;
+ final List<JCAnnotation> annos = typeAnnotationsOpt();
+
if (token.kind == LBRACKET) {
nextToken();
if ((mode & TYPE) != 0) {
@@ -1214,6 +1387,9 @@
mode = EXPR;
continue;
}
+ if (annos.nonEmpty()) {
+ t = toP(F.at(pos1).AnnotatedType(annos, t));
+ }
return t;
}
mode = oldmode;
@@ -1242,7 +1418,15 @@
t = innerCreator(pos2, typeArgs, t);
typeArgs = null;
} else {
+ List<JCAnnotation> 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;
}
@@ -1252,6 +1436,12 @@
accept(COLCOL);
t = memberReferenceSuffix(pos1, t);
} else {
+ if (!annos.isEmpty()) {
+ if (permitTypeAnnotationsPushBack)
+ typeAnnotationsPushedBack = annos;
+ else
+ return illegal(annos.head.pos);
+ }
break;
}
}
@@ -1274,7 +1464,7 @@
int pos = 0, depth = 0;
for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
switch (t.kind) {
- case IDENTIFIER: case QUES: case EXTENDS: case SUPER:
+ case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
case DOT: case RBRACKET: case LBRACKET: case COMMA:
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case CHAR:
@@ -1310,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:
@@ -1323,8 +1513,8 @@
if (peekToken(lookahead, RPAREN)) {
//Type, ')' -> cast
return ParensResult.CAST;
- } else if (peekToken(lookahead, IDENTIFIER)) {
- //Type, 'Identifier -> explicit lambda
+ } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
+ //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
}
break;
@@ -1350,16 +1540,19 @@
case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
case TRUE: case FALSE: case NULL:
- case NEW: case IDENTIFIER: case ASSERT: case ENUM:
+ case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
case BYTE: case SHORT: case CHAR: case INT:
case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
return ParensResult.CAST;
default:
return ParensResult.PARENS;
}
+ case UNDERSCORE:
+ case ASSERT:
+ case ENUM:
case IDENTIFIER:
- if (peekToken(lookahead, IDENTIFIER)) {
- // Identifier, Identifier -> explicit lambda
+ if (peekToken(lookahead, LAX_IDENTIFIER)) {
+ // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
} else if (peekToken(lookahead, RPAREN, ARROW)) {
// Identifier, ')' '->' -> implicit lambda
@@ -1368,12 +1561,39 @@
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, IDENTIFIER)) {
- // '[', ']', Identifier -> explicit lambda
+ if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
+ // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
} else if (peekToken(lookahead, RBRACKET, RPAREN) ||
peekToken(lookahead, RBRACKET, AMP)) {
@@ -1402,11 +1622,11 @@
// '>', ')' -> cast
// '>', '&' -> cast
return ParensResult.CAST;
- } else if (peekToken(lookahead, IDENTIFIER, COMMA) ||
- peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) ||
+ } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
+ peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
peekToken(lookahead, ELLIPSIS)) {
- // '>', Identifier, ',' -> explicit lambda
- // '>', Identifier, ')', '->' -> explicit lambda
+ // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
+ // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
// '>', '...' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
}
@@ -1426,6 +1646,13 @@
}
}
+ /** Accepts all identifier-like tokens */
+ Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
+ public boolean accepts(TokenKind t) {
+ return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
+ }
+ };
+
enum ParensResult {
CAST,
EXPLICIT_LAMBDA,
@@ -1433,21 +1660,9 @@
PARENS;
}
- JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) {
- ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
- params.append(firstParam);
- JCVariableDecl lastParam = firstParam;
- while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
- nextToken();
- params.append(lastParam = formalParameter());
- }
- accept(RPAREN);
- return lambdaExpressionOrStatementRest(params.toList(), pos);
- }
-
JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
List<JCVariableDecl> params = explicitParams ?
- formalParameters() :
+ formalParameters(true) :
implicitParameters(hasParens);
return lambdaExpressionOrStatementRest(params, pos);
@@ -1609,37 +1824,43 @@
/**
* {@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<JCAnnotation> 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);
- } else if (token.kind == IDENTIFIER) {
+ 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);
JCExpression wc = toP(F.at(pos).Wildcard(t, null));
JCIdent id = toP(F.at(token.pos).Ident(ident()));
JCErroneous err = F.at(pos).Erroneous(List.<JCTree>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) {
@@ -1648,22 +1869,51 @@
return toP(F.at(pos).TypeApply(t, args));
}
- /** BracketsOpt = {"[" "]"}
+ /**
+ * BracketsOpt = { [Annotations] "[" "]" }*
+ *
+ * <p>
+ *
+ * <code>annotations</code> is the list of annotations targeting
+ * the expression <code>t</code>.
*/
- private JCExpression bracketsOpt(JCExpression t) {
+ private JCExpression bracketsOpt(JCExpression t,
+ List<JCAnnotation> annotations) {
+ List<JCAnnotation> 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.<JCAnnotation>nil());
+ }
+
+ private JCExpression bracketsOptCont(JCExpression t, int pos,
+ List<JCAnnotation> 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
@@ -1677,8 +1927,8 @@
accept(CLASS);
if (token.pos == endPosTable.errorEndPos) {
// error recovery
- Name name = null;
- if (token.kind == IDENTIFIER) {
+ Name name;
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
name = token.name();
nextToken();
} else {
@@ -1715,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;
@@ -1728,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<JCExpression> typeArgs) {
+ List<JCAnnotation> 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;
@@ -1757,7 +2020,13 @@
}
int pos = token.pos;
nextToken();
+ List<JCAnnotation> 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();
@@ -1766,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");
@@ -1787,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);
@@ -1796,10 +2073,17 @@
}
}
- /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
+ /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
*/
JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
+ List<JCAnnotation> 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();
@@ -1809,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<JCAnnotation> 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.<JCExpression>nil(), null));
return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
}
} else {
ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
+
+ // maintain array dimension type annotations
+ ListBuffer<List<JCAnnotation>> dimAnnotations = ListBuffer.lb();
+ dimAnnotations.append(annos);
+
dims.append(parseExpression());
accept(RBRACKET);
- while (token.kind == LBRACKET) {
+ while (token.kind == LBRACKET
+ || token.kind == MONKEYS_AT) {
+ List<JCAnnotation> 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;
}
}
@@ -2026,10 +2340,7 @@
nextToken();
JCStatement stat = parseStatement();
return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
- } else if ((lastmode & TYPE) != 0 &&
- (token.kind == IDENTIFIER ||
- token.kind == ASSERT ||
- token.kind == ENUM)) {
+ } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
pos = token.pos;
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
F.at(pos);
@@ -2183,14 +2494,14 @@
}
case BREAK: {
nextToken();
- Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+ Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCBreak t = to(F.at(pos).Break(label));
accept(SEMI);
return t;
}
case CONTINUE: {
nextToken();
- Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+ Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCContinue t = to(F.at(pos).Continue(label));
accept(SEMI);
return t;
@@ -2248,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;
@@ -2270,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();
}
@@ -2351,9 +2665,7 @@
return variableDeclarators(optFinal(0), parseType(), stats).toList();
} else {
JCExpression t = term(EXPR | TYPE);
- if ((lastmode & TYPE) != 0 &&
- (token.kind == IDENTIFIER || token.kind == ASSERT ||
- token.kind == ENUM)) {
+ if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
return variableDeclarators(modifiersOpt(), t, stats).toList();
} else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
error(pos, "bad.initializer", "for-loop");
@@ -2373,16 +2685,28 @@
}
/** AnnotationsOpt = { '@' Annotation }
+ *
+ * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
*/
- List<JCAnnotation> annotationsOpt() {
+ List<JCAnnotation> annotationsOpt(Tag kind) {
if (token.kind != MONKEYS_AT) return List.nil(); // optimization
ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
+ 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<JCAnnotation> annotations = buf.toList();
+
+ return annotations;
+ }
+
+ List<JCAnnotation> typeAnnotationsOpt() {
+ List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
+ return annotations;
}
/** ModifiersOpt = { Modifier }
@@ -2408,7 +2732,7 @@
if (token.deprecatedFlag()) {
flags |= Flags.DEPRECATED;
}
- int lastPos = Position.NOPOS;
+ int lastPos;
loop:
while (true) {
long flag;
@@ -2435,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;
}
}
@@ -2464,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<JCExpression> 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;
}
@@ -2524,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);
@@ -2609,8 +2945,18 @@
/** VariableDeclaratorId = Ident BracketsOpt
*/
JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
+ return variableDeclaratorId(mods, type, false);
+ }
+ //where
+ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
int pos = token.pos;
- Name name = ident();
+ Name name;
+ if (lambdaParameter && token.kind == UNDERSCORE) {
+ syntaxError(pos, "expected", IDENTIFIER);
+ name = token.name();
+ } else {
+ name = ident();
+ }
if ((mods.flags & Flags.VARARGS) != 0 &&
token.kind == LBRACKET) {
log.error(token.pos, "varargs.and.old.array.syntax");
@@ -2669,7 +3015,7 @@
mods = null;
}
nextToken();
- pid = qualident();
+ pid = qualident(false);
accept(SEMI);
}
ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
@@ -2770,7 +3116,7 @@
} else {
int pos = token.pos;
List<JCTree> errs;
- if (token.kind == IDENTIFIER) {
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
setErrorEndPos(token.pos);
} else {
@@ -2787,7 +3133,7 @@
}
int pos = token.pos;
List<JCTree> errs;
- if (token.kind == IDENTIFIER) {
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
setErrorEndPos(token.pos);
} else {
@@ -2920,7 +3266,7 @@
flags |= Flags.DEPRECATED;
}
int pos = token.pos;
- List<JCAnnotation> annotations = annotationsOpt();
+ List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
List<JCExpression> typeArgs = typeArgumentsOpt();
int identPos = token.pos;
@@ -3023,15 +3369,25 @@
mods.pos = pos;
storeEnd(mods, pos);
}
+ List<JCAnnotation> 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)
@@ -3084,51 +3440,71 @@
List<JCTypeParameter> typarams,
boolean isInterface, boolean isVoid,
Comment dc) {
- List<JCVariableDecl> params = formalParameters();
- if (!isVoid) type = bracketsOpt(type);
- List<JCExpression> thrown = List.nil();
- if (token.kind == THROWS) {
- nextToken();
- thrown = qualidentList();
+ if (isInterface && (mods.flags & Flags.STATIC) != 0) {
+ checkStaticInterfaceMethods();
}
- 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<JCVariableDecl> params = formalParameters();
+ if (!isVoid) type = bracketsOpt(type);
+ List<JCExpression> 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<JCExpression> qualidentList() {
ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
- ts.append(qualident());
+
+ List<JCAnnotation> 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();
}
@@ -3157,13 +3533,14 @@
/**
* {@literal
- * TypeParameter = TypeVariable [TypeParameterBound]
+ * TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
* TypeParameterBound = EXTENDS Type {"&" Type}
* TypeVariable = Ident
* }
*/
JCTypeParameter typeParameter() {
int pos = token.pos;
+ List<JCAnnotation> annos = typeAnnotationsOpt();
Name name = ident();
ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
if (token.kind == EXTENDS) {
@@ -3174,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 ] ")"
@@ -3182,14 +3559,24 @@
* FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
*/
List<JCVariableDecl> formalParameters() {
+ return formalParameters(false);
+ }
+ List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
- JCVariableDecl lastParam = null;
+ JCVariableDecl lastParam;
accept(LPAREN);
if (token.kind != RPAREN) {
- params.append(lastParam = formalParameter());
+ 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());
+ params.append(lastParam = formalParameter(lambdaParameters));
}
}
accept(RPAREN);
@@ -3221,24 +3608,113 @@
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<JCAnnotation> 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
*/
protected JCVariableDecl formalParameter() {
+ return formalParameter(false);
+ }
+ 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<JCAnnotation> 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);
+ return variableDeclaratorId(mods, type, lambdaParameter);
}
protected JCVariableDecl implicitParameter() {
JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
- return variableDeclaratorId(mods, null);
+ return variableDeclaratorId(mods, null, true);
}
/* ---------- auxiliary methods -------------- */
@@ -3479,6 +3955,18 @@
allowIntersectionTypesInCast = true;
}
}
+ void checkStaticInterfaceMethods() {
+ if (!allowStaticInterfaceMethods) {
+ log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
+ 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
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Sat Jan 26 19:24:46 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<Token> savedTokens = new ArrayList<Token>();
private JavaTokenizer tokenizer;
+
/**
* Create a scanner from the input array. This method might
* modify the array. To avoid copying the input array, ensure
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java Sat Jan 26 19:24:46 2013 -0800
@@ -33,6 +33,7 @@
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Filter;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Names;
@@ -74,7 +75,6 @@
protected Tokens(Context context) {
context.put(tokensKey, this);
names = Names.instance(context);
-
for (TokenKind t : TokenKind.values()) {
if (t.name != null)
enterKeyword(t.name, t);
@@ -113,7 +113,7 @@
* This enum defines all tokens used by the javac scanner. A token is
* optionally associated with a name.
*/
- public enum TokenKind implements Formattable {
+ public enum TokenKind implements Formattable, Filter<TokenKind> {
EOF(),
ERROR(),
IDENTIFIER(Tag.NAMED),
@@ -176,6 +176,7 @@
TRUE("true", Tag.NAMED),
FALSE("false", Tag.NAMED),
NULL("null", Tag.NAMED),
+ UNDERSCORE("_", Tag.NAMED),
ARROW("->"),
COLCOL("::"),
LPAREN("("),
@@ -283,6 +284,11 @@
public String toString(Locale locale, Messages messages) {
return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
}
+
+ @Override
+ public boolean accepts(TokenKind that) {
+ return this == that;
+ }
}
public interface Comment {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java Sat Jan 26 19:24:46 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.
*
* <p><b>This is NOT part of any supported API.
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Sat Jan 26 19:24:46 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<PackageSymbol> 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<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> 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<JavaFileObject>(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);
+ }
};
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Jan 26 19:24:46 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
@@ -178,13 +178,22 @@
compiler.misc.incompatible.abstracts=\
multiple non-overriding abstract methods found in {0} {1}
-compiler.misc.not.a.functional.intf=\
- the target type must be a functional interface
+compiler.err.bad.functional.intf.anno=\
+ Unexpected @FunctionalInterface annotation
# 0: message segment
+compiler.err.bad.functional.intf.anno.1=\
+ Unexpected @FunctionalInterface annotation\n\
+ {0}
+
+# 0: symbol
+compiler.misc.not.a.functional.intf=\
+ {0} is not a functional interface
+
+# 0: symbol, 1: message segment
compiler.misc.not.a.functional.intf.1=\
- the target type must be a functional interface\n\
- {0}
+ {0} is not a functional interface\n\
+ {1}
# 0: symbol, 1: symbol kind, 2: symbol
compiler.misc.invalid.generic.lambda.target=\
@@ -319,64 +328,48 @@
compiler.err.duplicate.annotation.missing.container=\
duplicate annotation, the declaration of {0} does not have a valid {1} annotation
-# 0: type, 1: type
-compiler.err.invalid.container.no.containedby=\
- invalid contained repeatable annotation, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containedby=\
- invalid contained repeatable annotation, {0} does not match {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.no.containerfor=\
- invalid container for repeating annotations, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containerfor=\
- invalid container for repeating annotations, {0} does not match {1}
+# 0: type
+compiler.err.invalid.repeatable.annotation=\
+ duplicate annotation, {0} is annotated with an invalid Repeatable annotation
# 0: type
-compiler.err.invalid.containedby.annotation=\
- duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
-
-# 0: type
-compiler.err.invalid.containedby.annotation.no.value=\
- duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+compiler.err.invalid.repeatable.annotation.no.value=\
+ duplicate annotation, {0} is not a valid Repeatable, no value element method declared
# 0: type, 1: number
-compiler.err.invalid.containedby.annotation.multiple.values=\
- duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+compiler.err.invalid.repeatable.annotation.multiple.values=\
+ duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
# 0: type
-compiler.err.invalid.containedby.annotation.invalid.value=\
- duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+compiler.err.invalid.repeatable.annotation.invalid.value=\
+ duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
# 0: type, 1: type, 2: type
-compiler.err.invalid.containedby.annotation.value.return=\
+compiler.err.invalid.repeatable.annotation.value.return=\
duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
# 0: type, 1: symbol
-compiler.err.invalid.containedby.annotation.elem.nondefault=\
+compiler.err.invalid.repeatable.annotation.elem.nondefault=\
containing annotation {0} does not have a default value for element {1}
# 0: symbol, 1: type, 2: symbol, 3: type
-compiler.err.invalid.containedby.annotation.retention=\
+compiler.err.invalid.repeatable.annotation.retention=\
containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.documented=\
+compiler.err.invalid.repeatable.annotation.not.documented=\
containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.inherited=\
+compiler.err.invalid.repeatable.annotation.not.inherited=\
containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.incompatible.target=\
+compiler.err.invalid.repeatable.annotation.incompatible.target=\
target of container annotation {0} is not a subset of target of repeated annotation {1}
# 0: symbol
-compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\
container {0} must not be present at the same time as the element it contains
# 0: name
@@ -955,6 +948,11 @@
compiler.err.default.overrides.object.member=\
default method {0} in {1} {2} overrides a member of java.lang.Object
+# 0: type
+compiler.err.illegal.static.intf.meth.call=\
+ illegal static interface method call\n\
+ the receiver expression should be replaced with the type qualifier ''{0}''
+
# 0: type, 1: message segment
compiler.err.illegal.default.super.call=\
bad type qualifier {0} in default super call\n\
@@ -1668,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}
@@ -2139,6 +2140,10 @@
as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\
(use -source 1.4 or higher to use ''assert'' as a keyword)
+compiler.warn.underscore.as.identifier=\
+ ''_'' used as an identifier\n\
+ (use of ''_'' as an identifier might not be supported in future releases)
+
compiler.err.enum.as.identifier=\
as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
(use -source 1.4 or lower to use ''enum'' as an identifier)
@@ -2147,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\
@@ -2162,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=\
@@ -2216,6 +2239,11 @@
intersection types in cast are not supported in -source {0}\n\
(use -source 8 or higher to enable default methods)
+# 0: string
+compiler.err.static.intf.methods.not.supported.in.source=\
+ static interface methods are not supported in -source {0}\n\
+ (use -source 8 or higher to enable static interface methods)
+
########################################
# Diagnostics for verbose resolution
# used by Resolve (debug only)
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Sat Jan 26 19:24:46 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)
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Sat Jan 26 19:24:46 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)
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Sat Jan 26 19:24:46 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.
@@ -607,6 +613,42 @@
}
/**
+ * Common supertype for all poly expression trees (lambda, method references,
+ * conditionals, method and constructor calls)
+ */
+ public static abstract class JCPolyExpression extends JCExpression {
+
+ /**
+ * A poly expression can only be truly 'poly' in certain contexts
+ */
+ public enum PolyKind {
+ /** poly expression to be treated as a standalone expression */
+ STANDALONE,
+ /** true poly expression */
+ POLY;
+ }
+
+ /** is this poly expression a 'true' poly expression? */
+ public PolyKind polyKind;
+ }
+
+ /**
+ * Common supertype for all functional expression trees (lambda and method references)
+ */
+ public static abstract class JCFunctionalExpression extends JCPolyExpression {
+
+ public JCFunctionalExpression() {
+ //a functional expression is always a 'true' poly
+ polyKind = PolyKind.POLY;
+ }
+
+ /** target descriptor inferred for this functional expression. */
+ public Type descriptorType;
+ /** list of target types inferred for this functional expression. */
+ public List<TypeSymbol> targets;
+ }
+
+ /**
* A class definition.
*/
public static class JCClassDecl extends JCStatement implements ClassTree {
@@ -689,6 +731,8 @@
public JCExpression restype;
/** type parameters */
public List<JCTypeParameter> typarams;
+ /** receiver parameter */
+ public JCVariableDecl recvparam;
/** value parameters */
public List<JCVariableDecl> params;
/** exceptions thrown by this method */
@@ -703,6 +747,7 @@
Name name,
JCExpression restype,
List<JCTypeParameter> typarams,
+ JCVariableDecl recvparam,
List<JCVariableDecl> params,
List<JCExpression> thrown,
JCBlock body,
@@ -714,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.<JCTypeAnnotation>nil());
this.thrown = thrown;
this.body = body;
this.defaultValue = defaultValue;
@@ -732,6 +780,7 @@
public List<JCVariableDecl> getParameters() {
return params;
}
+ public JCVariableDecl getReceiverParameter() { return recvparam; }
public List<JCExpression> getThrows() {
return thrown;
}
@@ -1147,7 +1196,7 @@
/**
* A ( ) ? ( ) : ( ) conditional expression
*/
- public static class JCConditional extends JCExpression implements ConditionalExpressionTree {
+ public static class JCConditional extends JCPolyExpression implements ConditionalExpressionTree {
public JCExpression cond;
public JCExpression truepart;
public JCExpression falsepart;
@@ -1373,7 +1422,7 @@
/**
* A method invocation
*/
- public static class JCMethodInvocation extends JCExpression implements MethodInvocationTree {
+ public static class JCMethodInvocation extends JCPolyExpression implements MethodInvocationTree {
public List<JCExpression> typeargs;
public JCExpression meth;
public List<JCExpression> args;
@@ -1416,7 +1465,7 @@
/**
* A new(...) operation.
*/
- public static class JCNewClass extends JCExpression implements NewClassTree {
+ public static class JCNewClass extends JCPolyExpression implements NewClassTree {
public JCExpression encl;
public List<JCExpression> typeargs;
public JCExpression clazz;
@@ -1469,6 +1518,10 @@
public static class JCNewArray extends JCExpression implements NewArrayTree {
public JCExpression elemtype;
public List<JCExpression> dims;
+ // type annotations on inner-most component
+ public List<JCAnnotation> annotations;
+ // type annotations on dimensions
+ public List<List<JCAnnotation>> dimAnnotations;
public List<JCExpression> elems;
protected JCNewArray(JCExpression elemtype,
List<JCExpression> dims,
@@ -1476,6 +1529,8 @@
{
this.elemtype = elemtype;
this.dims = dims;
+ this.annotations = List.nil();
+ this.dimAnnotations = List.nil();
this.elems = elems;
}
@Override
@@ -1502,18 +1557,29 @@
/**
* A lambda expression.
*/
- public static class JCLambda extends JCExpression implements LambdaExpressionTree {
+ public static class JCLambda extends JCFunctionalExpression implements LambdaExpressionTree {
+
+ public enum ParameterKind {
+ IMPLICIT,
+ EXPLICIT;
+ }
public List<JCVariableDecl> params;
public JCTree body;
- public Type targetType;
public boolean canCompleteNormally = true;
public List<Type> inferredThrownTypes;
+ public ParameterKind paramKind;
public JCLambda(List<JCVariableDecl> params,
JCTree body) {
this.params = params;
this.body = body;
+ if (params.isEmpty() ||
+ params.head.vartype != null) {
+ paramKind = ParameterKind.EXPLICIT;
+ } else {
+ paramKind = ParameterKind.IMPLICIT;
+ }
}
@Override
public Tag getTag() {
@@ -1812,15 +1878,15 @@
/**
* Selects a member expression.
*/
- public static class JCMemberReference extends JCExpression implements MemberReferenceTree {
+ public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree {
public ReferenceMode mode;
public ReferenceKind kind;
public Name name;
public JCExpression expr;
public List<JCExpression> typeargs;
- public Type targetType;
public Symbol sym;
public Type varargsElement;
+ public PolyKind refPolyKind;
/**
* Javac-dependent classification for member references, based
@@ -1838,7 +1904,9 @@
/** Inner # new */
IMPLICIT_INNER(ReferenceMode.NEW, false),
/** Toplevel # new */
- TOPLEVEL(ReferenceMode.NEW, false);
+ TOPLEVEL(ReferenceMode.NEW, false),
+ /** ArrayType # new */
+ ARRAY_CTOR(ReferenceMode.NEW, false);
final ReferenceMode mode;
final boolean unbound;
@@ -2103,9 +2171,12 @@
public Name name;
/** bounds */
public List<JCExpression> bounds;
- protected JCTypeParameter(Name name, List<JCExpression> bounds) {
+ /** type annotations on type parameter */
+ public List<JCAnnotation> annotations;
+ protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annotations) {
this.name = name;
this.bounds = bounds;
+ this.annotations = annotations;
}
@Override
public void accept(Visitor v) { v.visitTypeParameter(this); }
@@ -2115,6 +2186,9 @@
public List<JCExpression> getBounds() {
return bounds;
}
+ public List<JCAnnotation> getAnnotations() {
+ return annotations;
+ }
@Override
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
return v.visitTypeParameter(this, d);
@@ -2181,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<JCExpression> args;
- protected JCAnnotation(JCTree annotationType, List<JCExpression> 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<JCExpression> 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<JCExpression> getArguments() {
return args;
@@ -2201,7 +2286,7 @@
}
@Override
public Tag getTag() {
- return ANNOTATION;
+ return tag;
}
}
@@ -2232,6 +2317,35 @@
}
}
+ public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree {
+ // type annotations
+ public List<JCAnnotation> annotations;
+ public JCExpression underlyingType;
+
+ protected JCAnnotatedType(List<JCAnnotation> 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<JCAnnotation> getAnnotations() {
+ return annotations;
+ }
+ public JCExpression getUnderlyingType() {
+ return underlyingType;
+ }
+ @Override
+ public <R,D> R accept(TreeVisitor<R,D> 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<? extends JCTree> errs;
@@ -2298,6 +2412,7 @@
Name name,
JCExpression restype,
List<JCTypeParameter> typarams,
+ JCVariableDecl recvparam,
List<JCVariableDecl> params,
List<JCExpression> thrown,
JCBlock body,
@@ -2423,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); }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Sat Jan 26 19:24:46 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<JCAnnotation> trees) throws IOException {
+ if (trees.nonEmpty())
+ print(" ");
+ for (List<JCAnnotation> 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<JCAnnotation> 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<List<JCAnnotation>> da = tree.dimAnnotations;
for (List<JCExpression> 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);
}
@@ -946,7 +981,7 @@
public void visitLambda(JCLambda tree) {
try {
print("(");
- if (TreeInfo.isExplicitLambda(tree)) {
+ if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT) {
printExprs(tree.params);
} else {
String sep = "";
@@ -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 + ")");
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Sat Jan 26 19:24:46 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<JCAnnotation> 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<JCExpression> 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<JCTypeParameter> typarams = copy(t.typarams, p);
List<JCVariableDecl> params = copy(t.params, p);
+ JCVariableDecl recvparam = copy(t.recvparam, p);
List<JCExpression> 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<JCAnnotation> annos = copy(t.annotations, p);
List<JCExpression> 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) {
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Sat Jan 26 19:24:46 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
@@ -32,6 +32,7 @@
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import static com.sun.tools.javac.code.Flags.*;
@@ -264,9 +265,38 @@
}
}
- public static boolean isExplicitLambda(JCLambda lambda) {
- return lambda.params.isEmpty() ||
- lambda.params.head.vartype != null;
+ /** set 'polyKind' on given tree */
+ public static void setPolyKind(JCTree tree, PolyKind pkind) {
+ switch (tree.getTag()) {
+ case APPLY:
+ ((JCMethodInvocation)tree).polyKind = pkind;
+ break;
+ case NEWCLASS:
+ ((JCNewClass)tree).polyKind = pkind;
+ break;
+ case REFERENCE:
+ ((JCMemberReference)tree).refPolyKind = pkind;
+ break;
+ default:
+ throw new AssertionError("Unexpected tree: " + tree);
+ }
+ }
+
+ /** set 'varargsElement' on given tree */
+ public static void setVarargsElement(JCTree tree, Type varargsElement) {
+ switch (tree.getTag()) {
+ case APPLY:
+ ((JCMethodInvocation)tree).varargsElement = varargsElement;
+ break;
+ case NEWCLASS:
+ ((JCNewClass)tree).varargsElement = varargsElement;
+ break;
+ case REFERENCE:
+ ((JCMemberReference)tree).varargsElement = varargsElement;
+ break;
+ default:
+ throw new AssertionError("Unexpected tree: " + tree);
+ }
}
/** Return true if the tree corresponds to an expression statement */
@@ -423,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)
@@ -530,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())
@@ -769,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;
}
@@ -1006,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 */
@@ -1024,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;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Sat Jan 26 19:24:46 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<JCExpression> 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<JCTypeParameter> typarams,
+ JCVariableDecl recvparam,
+ List<JCVariableDecl> params,
+ List<JCExpression> 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<JCExpression> bounds) {
- JCTypeParameter tree = new JCTypeParameter(name, bounds);
+ return TypeParameter(name, bounds, List.<JCAnnotation>nil());
+ }
+
+ public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) {
+ JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
tree.pos = pos;
return tree;
}
@@ -481,7 +501,13 @@
}
public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> 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<JCExpression> args) {
+ JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args);
tree.pos = pos;
return tree;
}
@@ -497,6 +523,12 @@
return Modifiers(flags, List.<JCAnnotation>nil());
}
+ public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
+ JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
+ tree.pos = pos;
+ return tree;
+ }
+
public JCErroneous Erroneous() {
return Erroneous(List.<JCTree>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<JCExpression> args = new ListBuffer<JCExpression>();
@@ -766,6 +802,15 @@
}
return Annotation(Type(compound.type), args.toList());
}
+ public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) {
+ ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
+ for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
+ Pair<MethodSymbol,Attribute> 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<JCExpression> elems = new ListBuffer<JCExpression>();
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<JCTypeParameter> TypeParams(List<Type> typarams) {
ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
- int i = 0;
for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
return tparams.toList();
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Sat Jan 26 19:24:46 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<JCAnnotation> 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) {
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Sat Jan 26 19:24:46 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<List<JCAnnotation>> dimAnnos = List.nil();
+ for (List<JCAnnotation> 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);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Sat Jan 26 19:24:46 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)
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Sat Jan 26 19:24:46 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;
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Sat Jan 26 19:24:46 2013 -0800
@@ -288,7 +288,7 @@
public String simplify(Symbol s) {
String name = s.getQualifiedName().toString();
- if (!s.type.isCompound()) {
+ if (!s.type.isCompound() && !s.type.isPrimitive()) {
List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
if (conflicts == null ||
(conflicts.size() == 1 &&
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java Sat Jan 26 19:24:46 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;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Sat Jan 26 19:24:46 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 <code>AnnotatedType</code>, 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<TypeCompound> 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();
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Sat Jan 26 19:24:46 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() {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,8 +31,10 @@
import javax.tools.JavaFileManager;
import com.sun.javadoc.*;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType;
@@ -105,6 +107,7 @@
Types types;
JavaFileManager fileManager;
Context context;
+ DocLint doclint;
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<JCTree, TreePath>();
@@ -400,6 +403,9 @@
public void warning(DocImpl doc, String key, String a1) {
if (silent)
return;
+ // suppress messages that have (probably) been covered by doclint
+ if (doclint != null && doc != null && key.startsWith("tag"))
+ return;
messager.warning(doc==null ? null : doc.position(), key, a1);
}
@@ -732,9 +738,15 @@
return p;
}
- TreePath getTreePath(JCCompilationUnit toplevel, JCTree tree) {
- // don't bother to cache paths for classes and members
- return new TreePath(getTreePath(toplevel), tree);
+ TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) {
+ TreePath p = treePaths.get(tree);
+ if (p == null)
+ treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree));
+ return p;
+ }
+
+ TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) {
+ return new TreePath(getTreePath(toplevel, cdecl), tree);
}
/**
@@ -781,4 +793,25 @@
result |= Modifier.VOLATILE;
return result;
}
+
+ void initDoclint(Collection<String> opts) {
+ ArrayList<String> doclintOpts = new ArrayList<String>();
+
+ for (String opt: opts) {
+ doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
+ }
+
+ if (doclintOpts.size() == 1
+ && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
+ return;
+ }
+
+ JavacTask t = BasicJavacTask.instance(context);
+ doclint = new DocLint();
+ doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
+ }
+
+ boolean showTagMessages() {
+ return (doclint == null);
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java Sat Jan 26 19:24:46 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
@@ -126,7 +126,13 @@
*/
Comment comment() {
if (comment == null) {
- comment = new Comment(this, documentation());
+ String d = documentation();
+ if (env.doclint != null
+ && treePath != null
+ && d.equals(getCommentText(treePath))) {
+ env.doclint.scan(treePath);
+ }
+ comment = new Comment(this, d);
}
return comment;
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Sat Jan 26 19:24:46 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<? extends Compound> 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.
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Sat Jan 26 19:24:46 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
@@ -72,7 +72,7 @@
super.visitMethodDef(tree);
MethodSymbol meth = tree.sym;
if (meth == null || meth.kind != Kinds.MTH) return;
- TreePath treePath = docenv.getTreePath(env.toplevel, tree);
+ TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree);
if (meth.isConstructor())
docenv.makeConstructorDoc(meth, treePath);
else if (isAnnotationTypeElement(meth))
@@ -90,7 +90,7 @@
if (tree.sym != null &&
tree.sym.kind == Kinds.VAR &&
!isParameter(tree.sym)) {
- docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, tree));
+ docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree));
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java Sat Jan 26 19:24:46 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.
--- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Sat Jan 26 19:24:46 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
@@ -26,13 +26,14 @@
package com.sun.tools.javadoc;
import java.io.IOException;
+import java.util.Collection;
import java.util.Locale;
+
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.javadoc.*;
-
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
@@ -375,4 +376,12 @@
public JavaFileManager getFileManager() {
return env.fileManager;
}
+
+ public void initDocLint(Collection<String> opts) {
+ env.initDoclint(opts);
+ }
+
+ public boolean showTagMessages() {
+ return env.showTagMessages();
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Sat Jan 26 19:24:46 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 <code>AnnotationTypeDoc</code> if it
* represents an annotation type. Array dimensions are ignored.
*/
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Sat Jan 26 19:24:46 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<Type> 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<TypeCompound> 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;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Sat Jan 26 19:24:46 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);
}
--- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Sat Jan 26 19:24:46 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);
--- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java Sat Jan 26 19:24:46 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;
--- a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java Sat Jan 26 19:24:46 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;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java Sat Jan 26 19:24:46 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class 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<Integer, List<Note>>();
+ 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<Note> list = pcMap.get(pc);
+ if (list == null)
+ pcMap.put(pc, list = new ArrayList<Note>());
+ list.add(note);
+ }
+
+ @Override
+ void writeDetails(Instruction instr) {
+ String indent = space(2); // get from Options?
+ int pc = instr.getPC();
+ List<Note> 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<Integer, List<Note>> pcMap;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The build state class captures the source code and generated artifacts
+ * from a build. There are usually two build states, the previous one (prev),
+ * loaded from the javac_state file, and the current one (now).
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class BuildState {
+ private Map<String,Module> modules = new HashMap<String,Module>();
+ private Map<String,Package> packages = new HashMap<String,Package>();
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ private Map<String,File> artifacts = new HashMap<String,File>();
+ // Map from package to a set of packages that depend on said package.
+ private Map<String,Set<String>> dependents = new HashMap<String,Set<String>>();
+
+ public Map<String,Module> modules() { return modules; }
+ public Map<String,Package> packages() { return packages; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+ public Map<String,Set<String>> dependents() { return dependents; }
+
+ /**
+ * Lookup a module from a name. Create the module if it does
+ * not exist yet.
+ */
+ public Module lookupModule(String mod) {
+ Module m = modules.get(mod);
+ if (m == null) {
+ m = new Module(mod, "???");
+ modules.put(mod, m);
+ }
+ return m;
+ }
+
+ /**
+ * Find a module from a given package name. For example:
+ * The package name "base:java.lang" will fetch the module named "base".
+ * The package name ":java.net" will fetch the default module.
+ */
+ Module findModuleFromPackageName(String pkg) {
+ int cp = pkg.indexOf(':');
+ assert(cp != -1);
+ String mod = pkg.substring(0, cp);
+ return lookupModule(mod);
+ }
+
+ /**
+ * Collect all packages, sources and artifacts for all modules
+ * into the build state.
+ *
+ * @param m The set of modules.
+ */
+ public void collectPackagesSourcesAndArtifacts(Map<String,Module> m) {
+ modules = m;
+ // Extract all the found packages.
+ for (Module i : modules.values()) {
+ for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+ Package p = packages.get(j.getKey());
+ // Check that no two different packages are stored under same name.
+ assert(p == null || p == j.getValue());
+ if (p == null) {
+ p = j.getValue();
+ packages.put(j.getKey(),j.getValue());
+ }
+ for (Map.Entry<String,Source> k : p.sources().entrySet()) {
+ Source s = sources.get(k.getKey());
+ // Check that no two different sources are stored under same name.
+ assert(s == null || s == k.getValue());
+ if (s == null) {
+ s = k.getValue();
+ sources.put(k.getKey(), k.getValue());
+ }
+ }
+ for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+ File f = artifacts.get(g.getKey());
+ // Check that no two artifacts are stored under the same file.
+ assert(f == null || f == g.getValue());
+ if (f == null) {
+ f = g.getValue();
+ artifacts.put(g.getKey(), g.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Collect all the artifacts of all modules and packages.
+ *
+ * @param m The set of modules.
+ */
+ public void collectArtifacts(Map<String,Module> m) {
+ modules = m;
+ // Extract all the found packages.
+ for (Module i : modules.values()) {
+ for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+ Package p = packages.get(j.getKey());
+ // Check that no two different packages are stored under same name.
+ assert(p == null || p == j.getValue());
+ p = j.getValue();
+ packages.put(j.getKey(),j.getValue());
+ for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+ File f = artifacts.get(g.getKey());
+ // Check that no two artifacts are stored under the same file.
+ assert(f == null || f == g.getValue());
+ artifacts.put(g.getKey(), g.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * Calculate the package dependents (ie the reverse of the dependencies).
+ */
+ public void calculateDependents() {
+ dependents = new HashMap<String,Set<String>>();
+ for (String s : packages.keySet()) {
+ Package p = packages.get(s);
+ for (String d : p.dependencies()) {
+ Set<String> ss = dependents.get(d);
+ if (ss == null) {
+ ss = new HashSet<String>();
+ dependents.put(d, ss);
+ }
+ // Add the dependent information to the global dependent map.
+ ss.add(s);
+ Package dp = packages.get(d);
+ // Also add the dependent information to the package specific map.
+ // Normally, you do not compile java.lang et al. Therefore
+ // there are several packages that p depends upon that you
+ // do not have in your state database. This is perfectly fine.
+ if (dp != null) {
+ // But this package did exist in the state database.
+ dp.addDependent(p.name());
+ }
+ }
+ }
+ }
+
+ /**
+ * Verify that the setModules method above did the right thing when
+ * running through the module->package->source structure.
+ */
+ public void checkInternalState(String msg, boolean linkedOnly, Map<String,Source> srcs) {
+ boolean baad = false;
+ Map<String,Source> original = new HashMap<String,Source>();
+ Map<String,Source> calculated = new HashMap<String,Source>();
+
+ for (String s : sources.keySet()) {
+ Source ss = sources.get(s);
+ if (ss.isLinkedOnly() == linkedOnly) {
+ calculated.put(s,ss);
+ }
+ }
+ for (String s : srcs.keySet()) {
+ Source ss = srcs.get(s);
+ if (ss.isLinkedOnly() == linkedOnly) {
+ original.put(s,ss);
+ }
+ }
+ if (original.size() != calculated.size()) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated are not the same size!");
+ baad = true;
+ }
+ if (!original.keySet().equals(calculated.keySet())) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated do not have the same domain!");
+ baad = true;
+ }
+ if (!baad) {
+ for (String s : original.keySet()) {
+ Source s1 = original.get(s);
+ Source s2 = calculated.get(s);
+ if (s1 == null || s2 == null || !s1.equals(s2)) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated have differing elements for "+s);
+ }
+ baad = true;
+ }
+ }
+ if (baad) {
+ for (String s : original.keySet()) {
+ Source ss = original.get(s);
+ Source sss = calculated.get(s);
+ if (sss == null) {
+ Log.error("The file "+s+" does not exist in calculated tree of sources.");
+ }
+ }
+ for (String s : calculated.keySet()) {
+ Source ss = calculated.get(s);
+ Source sss = original.get(s);
+ if (sss == null) {
+ Log.error("The file "+s+" does not exist in original set of found sources.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Load a module from the javac state file.
+ */
+ public Module loadModule(String l) {
+ Module m = Module.load(l);
+ modules.put(m.name(), m);
+ return m;
+ }
+
+ /**
+ * Load a package from the javac state file.
+ */
+ public Package loadPackage(Module lastModule, String l) {
+ Package p = Package.load(lastModule, l);
+ lastModule.addPackage(p);
+ packages.put(p.name(), p);
+ return p;
+ }
+
+ /**
+ * Load a source from the javac state file.
+ */
+ public Source loadSource(Package lastPackage, String l, boolean is_generated) {
+ Source s = Source.load(lastPackage, l, is_generated);
+ lastPackage.addSource(s);
+ sources.put(s.name(), s);
+ return s;
+ }
+
+ /**
+ * During an incremental compile we need to copy the old javac state
+ * information about packages that were not recompiled.
+ */
+ public void copyPackagesExcept(BuildState prev, Set<String> recompiled, Set<String> removed) {
+ for (String pkg : prev.packages().keySet()) {
+ // Do not copy recompiled or removed packages.
+ if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
+ Module mnew = findModuleFromPackageName(pkg);
+ Package pprev = prev.packages().get(pkg);
+ mnew.addPackage(pprev);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * The clean properties transform should not be necessary.
+ * Eventually we will cleanup the property file sources in the OpenJDK instead.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CleanProperties implements Transformer
+{
+ public void setExtra(String e) {
+ // Any extra information is ignored for clean properties.
+ }
+
+ public void setExtra(String[] a) {
+ // Any extra information is ignored for clean properties.
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependencies,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = pkgName.replace('.',File.separatorChar);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ boolean r = clean(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+ packageArtifacts);
+ if (r == false) {
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+
+ boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+ Map<String,Set<URI>> packageArtifacts)
+ {
+ // Load the properties file.
+ Properties p = new Properties();
+ try {
+ p.load(new FileInputStream(src));
+ } catch (IOException e) {
+ Log.error("Error reading file "+src.getPath());
+ return false;
+ }
+
+ // Sort the properties in increasing key order.
+ List<String> sortedKeys = new ArrayList<String>();
+ for (Object key : p.keySet()) {
+ sortedKeys.add((String)key);
+ }
+ Collections.sort(sortedKeys);
+ Iterator<String> keys = sortedKeys.iterator();
+
+ // Collect the properties into a string buffer.
+ StringBuilder data = new StringBuilder();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ data.append(CompileProperties.escape(key)+":"+CompileProperties.escape((String)p.get(key))+"\n");
+ }
+
+ String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+ File dest = new File(destFilename);
+
+ // Make sure the dest directories exist.
+ if (!dest.getParentFile().isDirectory()) {
+ if (!dest.getParentFile().mkdirs()) {
+ Log.error("Could not create the directory "+dest.getParentFile().getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A cleaned property file exists, and its timestamp is newer than the source.
+ // Assume that we do not need to clean!
+ // Thus we are done.
+ return true;
+ }
+
+ Log.info("Cleaning property file "+pkgNameF+File.separator+src.getName());
+ try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+ writer.write(data.toString());
+ } catch ( IOException e ) {
+ Log.error("Could not write file "+dest.getPath());
+ return false;
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileChunk.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A compile chunk is a list of sources/packages to be compiled. Possibly a subset of
+ * the total number of sources/packages to be compiled for this sjavac invocation.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileChunk implements Comparable<CompileChunk> {
+ public int numPackages;
+ public int numDependents;
+ public Set<URI> srcs = new HashSet<URI>();
+ public StringBuilder pkgNames = new StringBuilder();
+ public String pkgFromTos = "";
+
+ public int compareTo(CompileChunk c) {
+ if (numDependents == c.numDependents) return 0;
+ if (numDependents > c.numDependents) return -1;
+ return -1;
+ }
+
+ boolean equal(CompileChunk c) {
+ return numDependents == c.numDependents;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.Set;
+import java.util.Map;
+
+import com.sun.tools.sjavac.server.JavacServer;
+import com.sun.tools.sjavac.server.SysInfo;
+import java.io.PrintStream;
+
+/**
+ * This transform compiles a set of packages containing Java sources.
+ * The compile request is divided into separate sets of source files.
+ * For each set a separate request thread is dispatched to a javac server
+ * and the meta data is accumulated. The number of sets correspond more or
+ * less to the number of cores. Less so now, than it will in the future.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileJavaPackages implements Transformer {
+
+ // The current limited sharing of data between concurrent JavaCompilers
+ // in the server will not give speedups above 3 cores. Thus this limit.
+ // We hope to improve this in the future.
+ final static int limitOnConcurrency = 3;
+
+ String serverSettings;
+ public void setExtra(String e) {
+ serverSettings = e;
+ }
+
+ String[] args;
+ public void setExtra(String[] a) {
+ args = a;
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSources,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ final Map<String,Set<URI>> packageArtifacts,
+ final Map<String,Set<String>> packageDependencies,
+ final Map<String,String> packagePubapis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ boolean concurrentCompiles = true;
+
+ // Fetch the id.
+ String id = Util.extractStringOption("id", serverSettings);
+ if (id == null || id.equals("")) {
+ // No explicit id set. Create a random id so that the requests can be
+ // grouped properly in the server.
+ id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
+ }
+ // Only keep portfile and sjavac settings..
+ String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings);
+
+ // Get maximum heap size from the server!
+ SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err);
+ if (sysinfo.numCores == -1) {
+ Log.error("Could not query server for sysinfo!");
+ return false;
+ }
+ int numMBytes = (int)(sysinfo.maxMemory / ((long)(1024*1024)));
+ Log.debug("Server reports "+numMBytes+"MiB of memory and "+sysinfo.numCores+" cores");
+
+ if (numCores <= 0) {
+ // Set the requested number of cores to the number of cores on the server.
+ numCores = sysinfo.numCores;
+ Log.debug("Number of jobs not explicitly set, defaulting to "+sysinfo.numCores);
+ } else if (sysinfo.numCores < numCores) {
+ // Set the requested number of cores to the number of cores on the server.
+ Log.debug("Limiting jobs from explicitly set "+numCores+" to cores available on server: "+sysinfo.numCores);
+ numCores = sysinfo.numCores;
+ } else {
+ Log.debug("Number of jobs explicitly set to "+numCores);
+ }
+ // More than three concurrent cores does not currently give a speedup, at least for compiling the jdk
+ // in the OpenJDK. This will change in the future.
+ int numCompiles = numCores;
+ if (numCores > limitOnConcurrency) numCompiles = limitOnConcurrency;
+ // Split the work up in chunks to compiled.
+
+ int numSources = 0;
+ for (String s : pkgSrcs.keySet()) {
+ Set<URI> ss = pkgSrcs.get(s);
+ numSources += ss.size();
+ }
+
+ int sourcesPerCompile = numSources / numCompiles;
+
+ // For 64 bit Java, it seems we can compile the OpenJDK 8800 files with a 1500M of heap
+ // in a single chunk, with reasonable performance.
+ // For 32 bit java, it seems we need 1G of heap.
+ // Number experimentally determined when compiling the OpenJDK.
+ // Includes space for reasonably efficient garbage collection etc,
+ // Calculating backwards gives us a requirement of
+ // 1500M/8800 = 175 KiB for 64 bit platforms
+ // and 1G/8800 = 119 KiB for 32 bit platform
+ // for each compile.....
+ int kbPerFile = 175;
+ String osarch = System.getProperty("os.arch");
+ if (osarch.equals("i386")) {
+ // For 32 bit platforms, assume it is slightly smaller
+ // because of smaller object headers and pointers.
+ kbPerFile = 119;
+ }
+ int numRequiredMBytes = (kbPerFile*numSources)/1024;
+ Log.debug("For os.arch "+osarch+" the empirically determined heap required per file is "+kbPerFile+"KiB");
+ Log.debug("Server has "+numMBytes+"MiB of heap.");
+ Log.debug("Heuristics say that we need "+numRequiredMBytes+"MiB of heap for all source files.");
+ // Perform heuristics to see how many cores we can use,
+ // or if we have to the work serially in smaller chunks.
+ if (numMBytes < numRequiredMBytes) {
+ // Ouch, cannot fit even a single compile into the heap.
+ // Split it up into several serial chunks.
+ concurrentCompiles = false;
+ // Limit the number of sources for each compile to 500.
+ if (numSources < 500) {
+ numCompiles = 1;
+ sourcesPerCompile = numSources;
+ Log.debug("Compiling as a single source code chunk to stay within heap size limitations!");
+ } else if (sourcesPerCompile > 500) {
+ // This number is very low, and tuned to dealing with the OpenJDK
+ // where the source is >very< circular! In normal application,
+ // with less circularity the number could perhaps be increased.
+ numCompiles = numSources / 500;
+ sourcesPerCompile = numSources/numCompiles;
+ Log.debug("Compiling source as "+numCompiles+" code chunks serially to stay within heap size limitations!");
+ }
+ } else {
+ if (numCompiles > 1) {
+ // Ok, we can fit at least one full compilation on the heap.
+ float usagePerCompile = (float)numRequiredMBytes / ((float)numCompiles * (float)0.7);
+ int usage = (int)(usagePerCompile * (float)numCompiles);
+ Log.debug("Heuristics say that for "+numCompiles+" concurrent compiles we need "+usage+"MiB");
+ if (usage > numMBytes) {
+ // Ouch it does not fit. Reduce to a single chunk.
+ numCompiles = 1;
+ sourcesPerCompile = numSources;
+ // What if the relationship betweem number of compile_chunks and num_required_mbytes
+ // is not linear? Then perhaps 2 chunks would fit where 3 does not. Well, this is
+ // something to experiment upon in the future.
+ Log.debug("Limiting compile to a single thread to stay within heap size limitations!");
+ }
+ }
+ }
+
+ Log.debug("Compiling sources in "+numCompiles+" chunk(s)");
+
+ // Create the chunks to be compiled.
+ final CompileChunk[] compileChunks = createCompileChunks(pkgSrcs, oldPackageDependents,
+ numCompiles, sourcesPerCompile);
+
+ if (Log.isDebugging()) {
+ int cn = 1;
+ for (CompileChunk cc : compileChunks) {
+ Log.debug("Chunk "+cn+" for "+id+" ---------------");
+ cn++;
+ for (URI u : cc.srcs) {
+ Log.debug(""+u);
+ }
+ }
+ }
+
+ // The return values for each chunked compile.
+ final int[] rn = new int[numCompiles];
+ // The requets, might or might not run as a background thread.
+ final Thread[] requests = new Thread[numCompiles];
+
+ final Set<URI> fvisible_sources = visibleSources;
+ final Map<URI,Set<String>> fvisible_classes = visibleClasses;
+
+ long start = System.currentTimeMillis();
+
+ for (int i=0; i<numCompiles; ++i) {
+ final int ii = i;
+ final CompileChunk cc = compileChunks[i];
+
+ // Pass the num_cores and the id (appended with the chunk number) to the server.
+ final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+ii;
+ final PrintStream fout = out;
+ final PrintStream ferr = err;
+
+ requests[ii] = new Thread() {
+ @Override
+ public void run() {
+ rn[ii] = JavacServer.useServer(cleanedServerSettings,
+ Main.removeWrapperArgs(args),
+ cc.srcs,
+ fvisible_sources,
+ fvisible_classes,
+ packageArtifacts,
+ packageDependencies,
+ packagePubapis,
+ null,
+ fout, ferr);
+ }
+ };
+
+ if (cc.srcs.size() > 0) {
+ String numdeps = "";
+ if (cc.numDependents > 0) numdeps = "(with "+cc.numDependents+" dependents) ";
+ if (!incremental || cc.numPackages > 16) {
+ String info = "("+cc.pkgFromTos+")";
+ if (info.equals("( to )")) {
+ info = "";
+ }
+ Log.info("Compiling "+cc.srcs.size()+" files "+numdeps+"in "+cc.numPackages+" packages "+info);
+ } else {
+ Log.info("Compiling "+cc.pkgNames+numdeps);
+ }
+ if (concurrentCompiles) {
+ requests[ii].start();
+ }
+ else {
+ requests[ii].run();
+ // If there was an error, then stop early when running single threaded.
+ if (rn[i] != 0) {
+ return false;
+ }
+ }
+ }
+ }
+ if (concurrentCompiles) {
+ // If there are background threads for the concurrent compiles, then join them.
+ for (int i=0; i<numCompiles; ++i) {
+ try { requests[i].join(); } catch (InterruptedException e) { }
+ }
+ }
+
+ // Check the return values.
+ for (int i=0; i<numCompiles; ++i) {
+ if (compileChunks[i].srcs.size() > 0) {
+ if (rn[i] != 0) {
+ rc = false;
+ }
+ }
+ }
+ long duration = System.currentTimeMillis() - start;
+ long minutes = duration/60000;
+ long seconds = (duration-minutes*60000)/1000;
+ Log.debug("Compilation of "+numSources+" source files took "+minutes+"m "+seconds+"s");
+
+ return rc;
+ }
+
+
+ /**
+ * Split up the sources into compile chunks. If old package dependents information
+ * is available, sort the order of the chunks into the most dependent first!
+ * (Typically that chunk contains the java.lang package.) In the future
+ * we could perhaps improve the heuristics to put the sources into even more sensible chunks.
+ * Now the package are simple sorted in alphabetical order and chunked, then the chunks
+ * are sorted on how dependent they are.
+ *
+ * @param pkgSrcs The sources to compile.
+ * @param oldPackageDependents Old package dependents, if non-empty, used to sort the chunks.
+ * @param numCompiles The number of chunks.
+ * @param sourcesPerCompile The number of sources per chunk.
+ * @return
+ */
+ CompileChunk[] createCompileChunks(Map<String,Set<URI>> pkgSrcs,
+ Map<String,Set<String>> oldPackageDependents,
+ int numCompiles,
+ int sourcesPerCompile) {
+
+ CompileChunk[] compileChunks = new CompileChunk[numCompiles];
+ for (int i=0; i<compileChunks.length; ++i) {
+ compileChunks[i] = new CompileChunk();
+ }
+
+ // Now go through the packages and spread out the source on the different chunks.
+ int ci = 0;
+ // Sort the packages
+ String[] packageNames = pkgSrcs.keySet().toArray(new String[0]);
+ Arrays.sort(packageNames);
+ String from = null;
+ for (String pkgName : packageNames) {
+ CompileChunk cc = compileChunks[ci];
+ Set<URI> s = pkgSrcs.get(pkgName);
+ if (cc.srcs.size()+s.size() > sourcesPerCompile && ci < numCompiles-1) {
+ from = null;
+ ci++;
+ cc = compileChunks[ci];
+ }
+ cc.numPackages++;
+ cc.srcs.addAll(s);
+
+ // Calculate nice package names to use as information when compiling.
+ String justPkgName = Util.justPackageName(pkgName);
+ // Fetch how many packages depend on this package from the old build state.
+ Set<String> ss = oldPackageDependents.get(pkgName);
+ if (ss != null) {
+ // Accumulate this information onto this chunk.
+ cc.numDependents += ss.size();
+ }
+ if (from == null || from.trim().equals("")) from = justPkgName;
+ cc.pkgNames.append(justPkgName+"("+s.size()+") ");
+ cc.pkgFromTos = from+" to "+justPkgName;
+ }
+ // If we are compiling serially, sort the chunks, so that the chunk (with the most dependents) (usually the chunk
+ // containing java.lang.Object, is to be compiled first!
+ // For concurrent compilation, this does not matter.
+ Arrays.sort(compileChunks);
+ return compileChunks;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Compile properties transform a properties file into a Java source file.
+ * Java has built in support for reading properties from either a text file
+ * in the source or a compiled java source file.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileProperties implements Transformer
+{
+ // Any extra information passed from the command line, for example if:
+ // -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+ // then extra will be "sun.util.resources.LocaleNamesBundle"
+ String extra;
+
+ public void setExtra(String e) {
+ extra = e;
+ }
+
+ public void setExtra(String[] a) {
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err) {
+ boolean rc = true;
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = Util.toFileSystemPath(pkgName);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ boolean r = compile(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+ packageArtifacts);
+ if (r == false) {
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+
+ boolean compile(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+ Map<String,Set<URI>> packageArtifacts)
+ {
+ String superClass = "java.util.ListResourceBundle";
+
+ if (extra != null) {
+ superClass = extra;
+ }
+ // Load the properties file.
+ Properties p = new Properties();
+ try {
+ p.load(new FileInputStream(src));
+ } catch (IOException e) {
+ Log.error("Error reading file "+src.getPath());
+ return false;
+ }
+
+ // Calculate the name of the Java source file to be generated.
+ int dp = src.getName().lastIndexOf(".");
+ String classname = src.getName().substring(0,dp);
+
+ // Sort the properties in increasing key order.
+ List<String> sortedKeys = new ArrayList<String>();
+ for (Object key : p.keySet()) {
+ sortedKeys.add((String)key);
+ }
+ Collections.sort(sortedKeys);
+ Iterator<String> keys = sortedKeys.iterator();
+
+ // Collect the properties into a string buffer.
+ StringBuilder data = new StringBuilder();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ data.append(" { \"" + escape(key) + "\", \"" +
+ escape((String)p.get(key)) + "\" },\n");
+ }
+
+ // Create dest file name. It is derived from the properties file name.
+ String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+classname+".java";
+ File dest = new File(destFilename);
+
+ // Make sure the dest directories exist.
+ if (!dest.getParentFile().isDirectory()) {
+ if (!dest.getParentFile().mkdirs()) {
+ Log.error("Could not create the directory "+dest.getParentFile().getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A generated file exists, and its timestamp is newer than the source.
+ // Assume that we do not need to regenerate the dest file!
+ // Thus we are done.
+ return true;
+ }
+
+ String packageString = "package " + pkgNameF.replace(File.separatorChar,'.') + ";\n\n";
+
+ Log.info("Compiling property file "+pkgNameF+File.separator+src.getName());
+ try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+ MessageFormat format = new MessageFormat(FORMAT);
+ writer.write(format.format(new Object[] { packageString, classname, superClass, data }));
+ } catch ( IOException e ) {
+ Log.error("Could not write file "+dest.getPath());
+ return false;
+ }
+ return true;
+ }
+
+ private static final String FORMAT =
+ "{0}" +
+ "public final class {1} extends {2} '{'\n" +
+ " protected final Object[][] getContents() '{'\n" +
+ " return new Object[][] '{'\n" +
+ "{3}" +
+ " };\n" +
+ " }\n" +
+ "}\n";
+
+ public static String escape(String theString) {
+ int len = theString.length();
+ StringBuilder outBuffer = new StringBuilder(len*2);
+
+ for(int x=0; x<len; x++) {
+ char aChar = theString.charAt(x);
+ switch(aChar) {
+ case '\\':outBuffer.append('\\'); outBuffer.append('\\');
+ break;
+ case '\t':outBuffer.append('\\'); outBuffer.append('t');
+ break;
+ case '\n':outBuffer.append('\\'); outBuffer.append('n');
+ break;
+ case '\r':outBuffer.append('\\'); outBuffer.append('r');
+ break;
+ case '\f':outBuffer.append('\\'); outBuffer.append('f');
+ break;
+ default:
+ if ((aChar < 0x0020) || (aChar > 0x007e)) {
+ outBuffer.append('\\');
+ outBuffer.append('u');
+ outBuffer.append(toHex((aChar >> 12) & 0xF));
+ outBuffer.append(toHex((aChar >> 8) & 0xF));
+ outBuffer.append(toHex((aChar >> 4) & 0xF));
+ outBuffer.append(toHex( aChar & 0xF));
+ } else {
+ if (aChar == '"') {
+ outBuffer.append('\\');
+ }
+ outBuffer.append(aChar);
+ }
+ }
+ }
+ return outBuffer.toString();
+ }
+
+ private static char toHex(int nibble) {
+ return hexDigit[(nibble & 0xF)];
+ }
+
+ private static final char[] hexDigit = {
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * The copy file transform simply copies a matching file from -src to -d .
+ * Such files are typically images, xml documents and other data files.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CopyFile implements Transformer {
+
+ public void setExtra(String e) {
+ }
+
+ public void setExtra(String[] a) {
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePubapis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ String dest_filename;
+ File dest;
+
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = Util.toFileSystemPath(pkgName);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ File destDir;
+ destDir = new File(destRoot.getPath()+File.separator+pkgNameF);
+ dest_filename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+ dest = new File(dest_filename);
+
+ if (!destDir.isDirectory()) {
+ if (!destDir.mkdirs()) {
+ Log.error("Error: The copier could not create the directory "+
+ destDir.getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A copied file exists, and its timestamp is newer than the source.
+ continue;
+ }
+
+ Log.info("Copying "+pkgNameF+File.separator+src.getName());
+
+ try (InputStream fin = new FileInputStream(src);
+ OutputStream fout = new FileOutputStream(dest)) {
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = fin.read(buf)) > 0){
+ fout.write(buf, 0, len);
+ }
+ }
+ catch(IOException e){
+ Log.error("Could not copy the file "+src.getPath()+" to "+dest.getPath());
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.text.SimpleDateFormat;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * The javac state class maintains the previous (prev) and the current (now)
+ * build states and everything else that goes into the javac_state file.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavacState
+{
+ // The arguments to the compile. If not identical, then it cannot
+ // be an incremental build!
+ String theArgs;
+ // The number of cores limits how many threads are used for heavy concurrent work.
+ int numCores;
+
+ // The bin_dir/javac_state
+ private String javacStateFilename;
+ private File javacState;
+
+ // The previous build state is loaded from javac_state
+ private BuildState prev;
+ // The current build state is constructed during the build,
+ // then saved as the new javac_state.
+ private BuildState now;
+
+ // Something has changed in the javac_state. It needs to be saved!
+ private boolean needsSaving;
+ // If this is a new javac_state file, then do not print unnecessary messages.
+ private boolean newJavacState;
+
+ // These are packages where something has changed and the package
+ // needs to be recompiled. Actions that trigger recompilation:
+ // * source belonging to the package has changed
+ // * artifact belonging to the package is lost, or its timestamp has been changed.
+ // * an unknown artifact has appeared, we simply delete it, but we also trigger a recompilation.
+ // * a package that is tainted, taints all packages that depend on it.
+ private Set<String> taintedPackages;
+ // After a compile, the pubapis are compared with the pubapis stored in the javac state file.
+ // Any packages where the pubapi differ are added to this set.
+ // Later we use this set and the dependency information to taint dependent packages.
+ private Set<String> packagesWithChangedPublicApis;
+ // When a module-info.java file is changed, taint the module,
+ // then taint all modules that depend on that that module.
+ // A module dependency can occur directly through a require, or
+ // indirectly through a module that does a public export for the first tainted module.
+ // When all modules are tainted, then taint all packages belonging to these modules.
+ // Then rebuild. It is perhaps possible (and valuable?) to do a more finegrained examination of the
+ // change in module-info.java, but that will have to wait.
+ private Set<String> taintedModules;
+ // The set of all packages that has been recompiled.
+ // Copy over the javac_state for the packages that did not need recompilation,
+ // verbatim from the previous (prev) to the new (now) build state.
+ private Set<String> recompiledPackages;
+
+ // The output directories filled with tasty artifacts.
+ private File binDir, gensrcDir, headerDir;
+
+ // The current status of the file system.
+ private Set<File> binArtifacts;
+ private Set<File> gensrcArtifacts;
+ private Set<File> headerArtifacts;
+
+ // The status of the sources.
+ Set<Source> removedSources = null;
+ Set<Source> addedSources = null;
+ Set<Source> modifiedSources = null;
+
+ // Visible sources for linking. These are the only
+ // ones that -sourcepath is allowed to see.
+ Set<URI> visibleSrcs;
+
+ // Visible classes for linking. These are the only
+ // ones that -classpath is allowed to see.
+ // It maps from a classpath root to the set of visible classes for that root.
+ // If the set is empty, then all classes are visible for that root.
+ // It can also map from a jar file to the set of visible classes for that jar file.
+ Map<URI,Set<String>> visibleClasses;
+
+ // Setup two transforms that always exist.
+ private CopyFile copyFiles = new CopyFile();
+ private CompileJavaPackages compileJavaPackages = new CompileJavaPackages();
+
+ // Where to send stdout and stderr.
+ private PrintStream out, err;
+
+ JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState,
+ PrintStream o, PrintStream e) {
+ out = o;
+ err = e;
+ numCores = Main.findNumberOption(args, "-j");
+ theArgs = "";
+ for (String a : removeArgsNotAffectingState(args)) {
+ theArgs = theArgs+a+" ";
+ }
+ binDir = bd;
+ gensrcDir = gd;
+ headerDir = hd;
+ javacStateFilename = binDir.getPath()+File.separator+"javac_state";
+ javacState = new File(javacStateFilename);
+ if (removeJavacState && javacState.exists()) {
+ javacState.delete();
+ }
+ newJavacState = false;
+ if (!javacState.exists()) {
+ newJavacState = true;
+ // If there is no javac_state then delete the contents of all the artifact dirs!
+ // We do not want to risk building a broken incremental build.
+ // BUT since the makefiles still copy things straight into the bin_dir et al,
+ // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
+ if (!permitUnidentifiedArtifacts) {
+ deleteContents(binDir);
+ deleteContents(gensrcDir);
+ deleteContents(headerDir);
+ }
+ needsSaving = true;
+ }
+ prev = new BuildState();
+ now = new BuildState();
+ taintedPackages = new HashSet<String>();
+ recompiledPackages = new HashSet<String>();
+ packagesWithChangedPublicApis = new HashSet<String>();
+ }
+
+ public BuildState prev() { return prev; }
+ public BuildState now() { return now; }
+
+ /**
+ * Remove args not affecting the state.
+ */
+ static String[] removeArgsNotAffectingState(String[] args) {
+ String[] out = new String[args.length];
+ int j = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-j")) {
+ // Just skip it and skip following value
+ i++;
+ } else if (args[i].startsWith("--server:")) {
+ // Just skip it.
+ } else if (args[i].startsWith("--log=")) {
+ // Just skip it.
+ } else if (args[i].equals("--compare-found-sources")) {
+ // Just skip it and skip verify file name
+ i++;
+ } else {
+ // Copy argument.
+ out[j] = args[i];
+ j++;
+ }
+ }
+ String[] ret = new String[j];
+ System.arraycopy(out, 0, ret, 0, j);
+ return ret;
+ }
+
+ /**
+ * Specify which sources are visible to the compiler through -sourcepath.
+ */
+ public void setVisibleSources(Map<String,Source> vs) {
+ visibleSrcs = new HashSet<URI>();
+ for (String s : vs.keySet()) {
+ Source src = vs.get(s);
+ visibleSrcs.add(src.file().toURI());
+ }
+ }
+
+ /**
+ * Specify which classes are visible to the compiler through -classpath.
+ */
+ public void setVisibleClasses(Map<String,Source> vs) {
+ visibleSrcs = new HashSet<URI>();
+ for (String s : vs.keySet()) {
+ Source src = vs.get(s);
+ visibleSrcs.add(src.file().toURI());
+ }
+ }
+ /**
+ * Returns true if this is an incremental build.
+ */
+ public boolean isIncremental() {
+ return !prev.sources().isEmpty();
+ }
+
+ /**
+ * Find all artifacts that exists on disk.
+ */
+ public void findAllArtifacts() {
+ binArtifacts = findAllFiles(binDir);
+ gensrcArtifacts = findAllFiles(gensrcDir);
+ headerArtifacts = findAllFiles(headerDir);
+ }
+
+ /**
+ * Lookup the artifacts generated for this package in the previous build.
+ */
+ private Map<String,File> fetchPrevArtifacts(String pkg) {
+ Package p = prev.packages().get(pkg);
+ if (p != null) {
+ return p.artifacts();
+ }
+ return new HashMap<String,File>();
+ }
+
+ /**
+ * Delete all prev artifacts in the currently tainted packages.
+ */
+ public void deleteClassArtifactsInTaintedPackages() {
+ for (String pkg : taintedPackages) {
+ Map<String,File> arts = fetchPrevArtifacts(pkg);
+ for (File f : arts.values()) {
+ if (f.exists() && f.getName().endsWith(".class")) {
+ f.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Mark the javac_state file to be in need of saving and as a side effect,
+ * it gets a new timestamp.
+ */
+ private void needsSaving() {
+ needsSaving = true;
+ }
+
+ /**
+ * Save the javac_state file.
+ */
+ public void save() throws IOException {
+ if (!needsSaving) return;
+ try (FileWriter out = new FileWriter(javacStateFilename)) {
+ StringBuilder b = new StringBuilder();
+ long millisNow = System.currentTimeMillis();
+ Date d = new Date(millisNow);
+ SimpleDateFormat df =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
+ b.append("# javac_state ver 0.3 generated "+millisNow+" "+df.format(d)+"\n");
+ b.append("# This format might change at any time. Please do not depend on it.\n");
+ b.append("# M module\n");
+ b.append("# P package\n");
+ b.append("# S C source_tobe_compiled timestamp\n");
+ b.append("# S L link_only_source timestamp\n");
+ b.append("# G C generated_source timestamp\n");
+ b.append("# A artifact timestamp\n");
+ b.append("# D dependency\n");
+ b.append("# I pubapi\n");
+ b.append("# R arguments\n");
+ b.append("R ").append(theArgs).append("\n");
+
+ // Copy over the javac_state for the packages that did not need recompilation.
+ now.copyPackagesExcept(prev, recompiledPackages, new HashSet<String>());
+ // Save the packages, ie package names, dependencies, pubapis and artifacts!
+ // I.e. the lot.
+ Module.saveModules(now.modules(), b);
+
+ String s = b.toString();
+ out.write(s, 0, s.length());
+ }
+ }
+
+ /**
+ * Load a javac_state file.
+ */
+ public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir,
+ boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) {
+ JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
+ Module lastModule = null;
+ Package lastPackage = null;
+ Source lastSource = null;
+ boolean noFileFound = false;
+ boolean foundCorrectVerNr = false;
+ boolean newCommandLine = false;
+ boolean syntaxError = false;
+
+ try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+ for (;;) {
+ String l = in.readLine();
+ if (l==null) break;
+ if (l.length()>=3 && l.charAt(1) == ' ') {
+ char c = l.charAt(0);
+ if (c == 'M') {
+ lastModule = db.prev.loadModule(l);
+ } else
+ if (c == 'P') {
+ if (lastModule == null) { syntaxError = true; break; }
+ lastPackage = db.prev.loadPackage(lastModule, l);
+ } else
+ if (c == 'D') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadDependency(l);
+ } else
+ if (c == 'I') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadPubapi(l);
+ } else
+ if (c == 'A') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadArtifact(l);
+ } else
+ if (c == 'S') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastSource = db.prev.loadSource(lastPackage, l, false);
+ } else
+ if (c == 'G') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastSource = db.prev.loadSource(lastPackage, l, true);
+ } else
+ if (c == 'R') {
+ String ncmdl = "R "+db.theArgs;
+ if (!l.equals(ncmdl)) {
+ newCommandLine = true;
+ }
+ } else
+ if (c == '#') {
+ if (l.startsWith("# javac_state ver ")) {
+ int sp = l.indexOf(" ", 18);
+ if (sp != -1) {
+ String ver = l.substring(18,sp);
+ if (!ver.equals("0.3")) {
+ break;
+ }
+ foundCorrectVerNr = true;
+ }
+ }
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // Silently create a new javac_state file.
+ noFileFound = true;
+ } catch (IOException e) {
+ Log.info("Dropping old javac_state because of errors when reading it.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ foundCorrectVerNr = true;
+ newCommandLine = false;
+ syntaxError = false;
+ }
+ if (foundCorrectVerNr == false && !noFileFound) {
+ Log.info("Dropping old javac_state since it is of an old version.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ } else
+ if (newCommandLine == true && !noFileFound) {
+ Log.info("Dropping old javac_state since a new command line is used!");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ } else
+ if (syntaxError == true) {
+ Log.info("Dropping old javac_state since it contains syntax errors.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ }
+ db.prev.calculateDependents();
+ return db;
+ }
+
+ /**
+ * Mark a java package as tainted, ie it needs recompilation.
+ */
+ public void taintPackage(String name, String because) {
+ if (!taintedPackages.contains(name)) {
+ if (because != null) Log.debug("Tainting "+Util.justPackageName(name)+" because "+because);
+ // It has not been tainted before.
+ taintedPackages.add(name);
+ needsSaving();
+ Package nowp = now.packages().get(name);
+ if (nowp != null) {
+ for (String d : nowp.dependents()) {
+ taintPackage(d, because);
+ }
+ }
+ }
+ }
+
+ /**
+ * This packages need recompilation.
+ */
+ public Set<String> taintedPackages() {
+ return taintedPackages;
+ }
+
+ /**
+ * Clean out the tainted package set, used after the first round of compiles,
+ * prior to propagating dependencies.
+ */
+ public void clearTaintedPackages() {
+ taintedPackages = new HashSet<String>();
+ }
+
+ /**
+ * Go through all sources and check which have been removed, added or modified
+ * and taint the corresponding packages.
+ */
+ public void checkSourceStatus(boolean check_gensrc) {
+ removedSources = calculateRemovedSources();
+ for (Source s : removedSources) {
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), "source "+s.name()+" was removed");
+ }
+ }
+
+ addedSources = calculateAddedSources();
+ for (Source s : addedSources) {
+ String msg = null;
+ if (isIncremental()) {
+ // When building from scratch, there is no point
+ // printing "was added" for every file since all files are added.
+ // However for an incremental build it makes sense.
+ msg = "source "+s.name()+" was added";
+ }
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), msg);
+ }
+ }
+
+ modifiedSources = calculateModifiedSources();
+ for (Source s : modifiedSources) {
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), "source "+s.name()+" was modified");
+ }
+ }
+ }
+
+ /**
+ * Acquire the compile_java_packages suffix rule for .java files.
+ */
+ public Map<String,Transformer> getJavaSuffixRule() {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ sr.put(".java", compileJavaPackages);
+ return sr;
+ }
+
+ /**
+ * Acquire the copying transform.
+ */
+ public Transformer getCopier() {
+ return copyFiles;
+ }
+
+ /**
+ * If artifacts have gone missing, force a recompile of the packages
+ * they belong to.
+ */
+ public void taintPackagesThatMissArtifacts() {
+ for (Package pkg : prev.packages().values()) {
+ for (File f : pkg.artifacts().values()) {
+ if (!f.exists()) {
+ // Hmm, the artifact on disk does not exist! Someone has removed it....
+ // Lets rebuild the package.
+ taintPackage(pkg.name(), ""+f+" is missing.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Propagate recompilation through the dependency chains.
+ * Avoid re-tainting packages that have already been compiled.
+ */
+ public void taintPackagesDependingOnChangedPackages(Set<String> pkgs, Set<String> recentlyCompiled) {
+ for (Package pkg : prev.packages().values()) {
+ for (String dep : pkg.dependencies()) {
+ if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
+ taintPackage(pkg.name(), " its depending on "+dep);
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan all output dirs for artifacts and remove those files (artifacts?)
+ * that are not recognized as such, in the javac_state file.
+ */
+ public void removeUnidentifiedArtifacts() {
+ Set<File> allKnownArtifacts = new HashSet<File>();
+ for (Package pkg : prev.packages().values()) {
+ for (File f : pkg.artifacts().values()) {
+ allKnownArtifacts.add(f);
+ }
+ }
+ // Do not forget about javac_state....
+ allKnownArtifacts.add(javacState);
+
+ for (File f : binArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ for (File f : headerArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ for (File f : gensrcArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ }
+
+ /**
+ * Remove artifacts that are no longer produced when compiling!
+ */
+ public void removeSuperfluousArtifacts(Set<String> recentlyCompiled) {
+ // Nothing to do, if nothing was recompiled.
+ if (recentlyCompiled.size() == 0) return;
+
+ for (String pkg : now.packages().keySet()) {
+ // If this package has not been recompiled, skip the check.
+ if (!recentlyCompiled.contains(pkg)) continue;
+ Collection<File> arts = now.artifacts().values();
+ for (File f : fetchPrevArtifacts(pkg).values()) {
+ if (!arts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is now superfluous!");
+ if (f.exists()) f.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Return those files belonging to prev, but not now.
+ */
+ private Set<Source> calculateRemovedSources() {
+ Set<Source> removed = new HashSet<Source>();
+ for (String src : prev.sources().keySet()) {
+ if (now.sources().get(src) == null) {
+ removed.add(prev.sources().get(src));
+ }
+ }
+ return removed;
+ }
+
+ /**
+ * Return those files belonging to now, but not prev.
+ */
+ private Set<Source> calculateAddedSources() {
+ Set<Source> added = new HashSet<Source>();
+ for (String src : now.sources().keySet()) {
+ if (prev.sources().get(src) == null) {
+ added.add(now.sources().get(src));
+ }
+ }
+ return added;
+ }
+
+ /**
+ * Return those files where the timestamp is newer.
+ * If a source file timestamp suddenly is older than what is known
+ * about it in javac_state, then consider it modified, but print
+ * a warning!
+ */
+ private Set<Source> calculateModifiedSources() {
+ Set<Source> modified = new HashSet<Source>();
+ for (String src : now.sources().keySet()) {
+ Source n = now.sources().get(src);
+ Source t = prev.sources().get(src);
+ if (prev.sources().get(src) != null) {
+ if (t != null) {
+ if (n.lastModified() > t.lastModified()) {
+ modified.add(n);
+ } else if (n.lastModified() < t.lastModified()) {
+ modified.add(n);
+ Log.warn("The source file "+n.name()+" timestamp has moved backwards in time.");
+ }
+ }
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Recursively delete a directory and all its contents.
+ */
+ private static void deleteContents(File dir) {
+ if (dir != null && dir.exists()) {
+ for (File f : dir.listFiles()) {
+ if (f.isDirectory()) {
+ deleteContents(f);
+ }
+ f.delete();
+ }
+ }
+ }
+
+ /**
+ * Run the copy translator only.
+ */
+ public void performCopying(File binDir, Map<String,Transformer> suffixRules) {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+ if (e.getValue() == copyFiles) {
+ sr.put(e.getKey(), e.getValue());
+ }
+ }
+ perform(binDir, sr);
+ }
+
+ /**
+ * Run all the translators that translate into java source code.
+ * I.e. all translators that are not copy nor compile_java_source.
+ */
+ public void performTranslation(File gensrcDir, Map<String,Transformer> suffixRules) {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+ if (e.getValue() != copyFiles &&
+ e.getValue() != compileJavaPackages) {
+ sr.put(e.getKey(), e.getValue());
+ }
+ }
+ perform(gensrcDir, sr);
+ }
+
+ /**
+ * Compile all the java sources. Return true, if it needs to be called again!
+ */
+ public boolean performJavaCompilations(File binDir,
+ String serverSettings,
+ String[] args,
+ Set<String> recentlyCompiled,
+ boolean[] rcValue) {
+ Map<String,Transformer> suffixRules = new HashMap<String,Transformer>();
+ suffixRules.put(".java", compileJavaPackages);
+ compileJavaPackages.setExtra(serverSettings);
+ compileJavaPackages.setExtra(args);
+
+ rcValue[0] = perform(binDir, suffixRules);
+ recentlyCompiled.addAll(taintedPackages());
+ clearTaintedPackages();
+ boolean again = !packagesWithChangedPublicApis.isEmpty();
+ taintPackagesDependingOnChangedPackages(packagesWithChangedPublicApis, recentlyCompiled);
+ packagesWithChangedPublicApis = new HashSet<String>();
+ return again && rcValue[0];
+ }
+
+ /**
+ * Store the source into the set of sources belonging to the given transform.
+ */
+ private void addFileToTransform(Map<Transformer,Map<String,Set<URI>>> gs, Transformer t, Source s) {
+ Map<String,Set<URI>> fs = gs.get(t);
+ if (fs == null) {
+ fs = new HashMap<String,Set<URI>>();
+ gs.put(t, fs);
+ }
+ Set<URI> ss = fs.get(s.pkg().name());
+ if (ss == null) {
+ ss = new HashSet<URI>();
+ fs.put(s.pkg().name(), ss);
+ }
+ ss.add(s.file().toURI());
+ }
+
+ /**
+ * For all packages, find all sources belonging to the package, group the sources
+ * based on their transformers and apply the transformers on each source code group.
+ */
+ private boolean perform(File outputDir, Map<String,Transformer> suffixRules)
+ {
+ boolean rc = true;
+ // Group sources based on transforms. A source file can only belong to a single transform.
+ Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<Transformer,Map<String,Set<URI>>>();
+ for (Source src : now.sources().values()) {
+ Transformer t = suffixRules.get(src.suffix());
+ if (t != null) {
+ if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
+ addFileToTransform(groupedSources, t, src);
+ }
+ }
+ }
+ // Go through the transforms and transform them.
+ for (Map.Entry<Transformer,Map<String,Set<URI>>> e : groupedSources.entrySet()) {
+ Transformer t = e.getKey();
+ Map<String,Set<URI>> srcs = e.getValue();
+ // These maps need to be synchronized since multiple threads will be writing results into them.
+ Map<String,Set<URI>> packageArtifacts = Collections.synchronizedMap(new HashMap<String,Set<URI>>());
+ Map<String,Set<String>> packageDependencies = Collections.synchronizedMap(new HashMap<String,Set<String>>());
+ Map<String,String> packagePublicApis = Collections.synchronizedMap(new HashMap<String,String>());
+
+ boolean r = t.transform(srcs,
+ visibleSrcs,
+ visibleClasses,
+ prev.dependents(),
+ outputDir.toURI(),
+ packageArtifacts,
+ packageDependencies,
+ packagePublicApis,
+ 0,
+ isIncremental(),
+ numCores,
+ out,
+ err);
+ if (!r) rc = false;
+
+ for (String p : srcs.keySet()) {
+ recompiledPackages.add(p);
+ }
+ // The transform is done! Extract all the artifacts and store the info into the Package objects.
+ for (Map.Entry<String,Set<URI>> a : packageArtifacts.entrySet()) {
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.addArtifacts(a.getKey(), a.getValue());
+ }
+ // Extract all the dependencies and store the info into the Package objects.
+ for (Map.Entry<String,Set<String>> a : packageDependencies.entrySet()) {
+ Set<String> deps = a.getValue();
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.setDependencies(a.getKey(), deps);
+ }
+ // Extract all the pubapis and store the info into the Package objects.
+ for (Map.Entry<String,String> a : packagePublicApis.entrySet()) {
+ Module mprev = prev.findModuleFromPackageName(a.getKey());
+ List<String> pubapi = Package.pubapiToList(a.getValue());
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.setPubapi(a.getKey(), pubapi);
+ if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
+ // Aha! The pubapi of this package has changed!
+ // It can also be a new compile from scratch.
+ if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
+ // This is an incremental compile! The pubapi
+ // did change. Trigger recompilation of dependents.
+ packagesWithChangedPublicApis.add(a.getKey());
+ Log.info("The pubapi of "+Util.justPackageName(a.getKey())+" has changed!");
+ }
+ }
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Utility method to recursively find all files below a directory.
+ */
+ private static Set<File> findAllFiles(File dir) {
+ Set<File> foundFiles = new HashSet<File>();
+ if (dir == null) {
+ return foundFiles;
+ }
+ recurse(dir, foundFiles);
+ return foundFiles;
+ }
+
+ private static void recurse(File dir, Set<File> foundFiles) {
+ for (File f : dir.listFiles()) {
+ if (f.isFile()) {
+ foundFiles.add(f);
+ } else if (f.isDirectory()) {
+ recurse(f, foundFiles);
+ }
+ }
+ }
+
+ /**
+ * Compare the calculate source list, with an explicit list, usually supplied from the makefile.
+ * Used to detect bugs where the makefile and sjavac have different opinions on which files
+ * should be compiled.
+ */
+ public void compareWithMakefileList(File makefileSourceList)
+ throws ProblemException
+ {
+ // If we are building on win32 using for example cygwin the paths in the makefile source list
+ // might be /cygdrive/c/.... which does not match c:\....
+ // We need to adjust our calculated sources to be identical, if necessary.
+ boolean mightNeedRewriting = File.pathSeparatorChar == ';';
+
+ if (makefileSourceList == null) return;
+
+ Set<String> calculatedSources = new HashSet<String>();
+ Set<String> listedSources = new HashSet<String>();
+
+ // Create a set of filenames with full paths.
+ for (Source s : now.sources().values()) {
+ calculatedSources.add(s.file().getPath());
+ }
+ // Read in the file and create another set of filenames with full paths.
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(makefileSourceList));
+ for (;;) {
+ String l = in.readLine();
+ if (l==null) break;
+ l = l.trim();
+ if (mightNeedRewriting) {
+ if (l.indexOf(":") == 1 && l.indexOf("\\") == 2) {
+ // Everything a-ok, the format is already C:\foo\bar
+ } else if (l.indexOf(":") == 1 && l.indexOf("/") == 2) {
+ // The format is C:/foo/bar, rewrite into the above format.
+ l = l.replaceAll("/","\\\\");
+ } else if (l.charAt(0) == '/' && l.indexOf("/",1) != -1) {
+ // The format might be: /cygdrive/c/foo/bar, rewrite into the above format.
+ // Do not hardcode the name cygdrive here.
+ int slash = l.indexOf("/",1);
+ l = l.replaceAll("/","\\\\");
+ l = ""+l.charAt(slash+1)+":"+l.substring(slash+2);
+ }
+ if (Character.isLowerCase(l.charAt(0))) {
+ l = Character.toUpperCase(l.charAt(0))+l.substring(1);
+ }
+ }
+ listedSources.add(l);
+ }
+ } catch (FileNotFoundException e) {
+ throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!");
+ } catch (IOException e) {
+ throw new ProblemException("Could not read "+makefileSourceList.getPath());
+ }
+
+ for (String s : listedSources) {
+ if (!calculatedSources.contains(s)) {
+ throw new ProblemException("The makefile listed source "+s+" was not calculated by the smart javac wrapper!");
+ }
+ }
+
+ for (String s : calculatedSources) {
+ if (!listedSources.contains(s)) {
+ throw new ProblemException("The smart javac wrapper calculated source "+s+" was not listed by the makefiles!");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.PrintStream;
+
+/**
+ * Utility class only for sjavac logging.
+ * The log level can be set using for example --log=DEBUG on the sjavac command line.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Log {
+ private static PrintStream out, err;
+
+ public final static int WARN = 1;
+ public final static int INFO = 2;
+ public final static int DEBUG = 3;
+ public final static int TRACE = 4;
+ private static int level = WARN;
+
+ static public void trace(String msg) {
+ if (level >= TRACE) {
+ out.println(msg);
+ }
+ }
+
+ static public void debug(String msg) {
+ if (level >= DEBUG) {
+ out.println(msg);
+ }
+ }
+
+ static public void info(String msg) {
+ if (level >= INFO) {
+ out.println(msg);
+ }
+ }
+
+ static public void warn(String msg) {
+ err.println(msg);
+ }
+
+ static public void error(String msg) {
+ err.println(msg);
+ }
+
+ static public void setLogLevel(String l, PrintStream o, PrintStream e)
+ throws ProblemException {
+ out = o;
+ err = e;
+ if (l.equals("warn")) level = WARN;
+ else if (l.equals("info")) level = INFO;
+ else if (l.equals("debug")) level = DEBUG;
+ else if (l.equals("trace")) level = TRACE;
+ else throw new ProblemException("No such log level \""+l+"\"");
+ }
+
+ static public boolean isTracing() {
+ return level >= TRACE;
+ }
+
+ static public boolean isDebugging() {
+ return level >= DEBUG;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.sun.tools.sjavac.server.JavacServer;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.*;
+
+/**
+ * The main class of the smart javac wrapper tool.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Main {
+
+ /* This is a smart javac wrapper primarily used when building the OpenJDK,
+ though other projects are welcome to use it too. But please be aware
+ that it is not an official api and will change in the future.
+ (We really mean it!)
+
+ Goals:
+
+ ** Create a state file, containing information about the build, so
+ that incremental builds only rebuild what is necessary. Also the
+ state file can be used by make/ant to detect when to trigger
+ a call to the smart javac wrapper.
+
+ This file is called bin/javac_state (assuming that you specified "-d bin")
+ Thus the simplest makefile is:
+
+ SJAVAC=java -cp .../tools.jar com.sun.tools.sjavac.Main
+ SRCS=$(shell find src -name "*.java")
+ bin/javac_state : $(SRCS)
+ $(SJAVAC) src -d bin
+
+ This makefile will run very fast and detect properly when Java code needs to
+ be recompiled. The smart javac wrapper will then use the information in java_state
+ to do an efficient incremental compile.
+
+ Previously it was near enough impossible to write an efficient makefile for Java
+ with support for incremental builds and dependency tracking.
+
+ ** Separate java sources to be compiled from java
+ sources used >only< for linking. The options:
+
+ "dir" points to root dir with sources to be compiled
+ "-sourcepath dir" points to root dir with sources used only for linking
+ "-classpath dir" points to dir with classes used only for linking (as before)
+
+ ** Use all cores for compilation by default.
+ "-j 4" limit the number of cores to 4.
+ For the moment, the sjavac server additionally limits the number of cores to three.
+ This will improve in the future when more sharing is performed between concurrent JavaCompilers.
+
+ ** Basic translation support from other sources to java, and then compilation of the generated java.
+ This functionality might be moved into annotation processors instead.
+ Again this is driven by the OpenJDK sources where properties and a few other types of files
+ are converted into Java sources regularily. The javac_state embraces copy and tr, and perform
+ incremental recompiles and copying for these as well. META-INF will be a special copy rule
+ that will copy any files found below any META-INF dir in src to the bin/META-INF dir.
+ "-copy .gif"
+ "-copy META-INF"
+ "-tr .prop=com.sun.tools.javac.smart.CompileProperties
+ "-tr .propp=com.sun.tools.javac.smart.CompileProperties,java.util.ListResourceBundle
+ "-tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+
+ ** Control which classes in the src,sourcepath and classpath that javac is allowed to see.
+ Again, this is necessary to deal with the source code structure of the OpenJDK which is
+ intricate (read messy).
+
+ "-i tools.*" to include the tools package and all its subpackages in the build.
+ "-x tools.net.aviancarrier.*" to exclude the aviancarrier package and all its sources and subpackages.
+ "-x tools.net.drums" to exclude the drums package only, keep its subpackages.
+ "-xf tools/net/Bar.java" // Do not compile this file...
+ "-xf *Bor.java" // Do not compile Bor.java wherever it is found, BUT do compile ABor.java!
+ "-if tools/net/Bor.java" // Only compile this file...odd, but sometimes used.
+
+ ** The smart javac wrapper is driven by the modification time on the source files and compared
+ to the modification times written into the javac_state file.
+
+ It does not compare the modification time of the source with the modification time of the artifact.
+ However it will detect if the modification time of an artifact has changed compared to the java_state,
+ and this will trigger a delete of the artifact and a subsequent recompile of the source.
+
+ The smart javac wrapper is not a generic makefile/ant system. Its purpose is to compile java source
+ as the final step before the output dir is finalized and immediately jared, or jmodded. The output
+ dir should be considered opaque. Do not write into the outputdir yourself!
+ Any artifacts found in the outputdir that javac_state does not know of, will be deleted!
+ This can however be prevented, using the switch --permit-unidentified-artifacts
+ This switch is necessary when build the OpenJDK because its makefiles still write directly to
+ the output classes dirs.
+
+ Any makefile/ant rules that want to put contents into the outputdir should put the content
+ in one of several source roots. Static content that is under version control, can be put in the same source
+ code tree as the Java sources. Dynamic content that is generated by make/ant on the fly, should
+ be put in a separate gensrc_stuff root. The smart javac wrapper call will then take the arguments:
+ "gensrc_stuff src -d bin"
+
+ The command line:
+ java -cp tools.jar com.sun.tools.sjavac.Main \
+ -i "com.bar.*" -x "com.bar.foo.*" \
+ first_root \
+ -i "com.bar.foo.*" \
+ second_root \
+ -x "org.net.*" \
+ -sourcepath link_root_sources \
+ -classpath link_root_classes \
+ -d bin
+
+ Will compile all sources for package com.bar and its subpackages, found below first_root,
+ except the package com.bar.foo (and its subpackages), for which the sources are picked
+ from second_root instead. It will link against classes in link_root_classes and against
+ sources in link_root_sources, but will not see (try to link against) sources matching org.net.*
+ but will link against org.net* classes (if they exist) in link_root_classes.
+
+ (If you want a set of complex filter rules to be applied to several source directories, without
+ having to repeat the the filter rules for each root. You can use the explicit -src option. For example:
+ sjavac -x "com.foo.*" -src root1:root2:root3 )
+
+ The resulting classes are written into bin.
+ */
+
+ // This is the final destination for classes and copied files.
+ private File bin_dir;
+ // This is where the annotation process will put generated sources.
+ private File gensrc_dir;
+ // This is where javac -h puts the generated c-header files.
+ private File header_dir;
+
+ // This file contains the list of sources genereated by the makefile.
+ // We double check that our calculated list of sources matches this list,
+ // if not, then we terminate with an error!
+ private File makefile_source_list;
+ // The challenging task to manage an incremental build is done by javac_state.
+ private JavacState javac_state;
+
+ // The suffix rules tells you for example, that .java files should be compiled,
+ // and .html files should be copied and .properties files be translated.
+ Map<String,Transformer> suffix_rules;
+
+ public static void main(String... args) {
+ if (args.length > 0 && args[0].startsWith("--startserver:")) {
+ if (args.length>1) {
+ Log.error("When spawning a background server, only a single --startserver argument is allowed.");
+ return;
+ }
+ // Spawn a background server.
+ int rc = JavacServer.startServer(args[0], System.err);
+ System.exit(rc);
+ }
+ Main main = new Main();
+ int rc = main.go(args, System.out, System.err);
+ // Remove the portfile, but only if this background=false was used.
+ JavacServer.cleanup(args);
+ System.exit(rc);
+ }
+
+ private void printHelp() {
+ System.out.println("Usage: sjavac <options>\n"+
+ "where required options are:\n"+
+ "dir Compile all sources in dir recursively\n"+
+ "-d dir Store generated classes here and the javac_state file\n"+
+ "--server:portfile=/tmp/abc Use a background sjavac server\n\n"+
+ "All other arguments as javac, except -implicit:none which is forced by default.\n"+
+ "No java source files can be supplied on the command line, nor can an @file be supplied.\n\n"+
+ "Warning!\n"+
+ "This tool might disappear at any time, and its command line options might change at any time!");
+ }
+
+ public int go(String[] args, PrintStream out, PrintStream err) {
+ try {
+ if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) {
+ printHelp();
+ return 0;
+ }
+
+ Log.setLogLevel(findLogLevel(args), out, err);
+ String server_settings = Util.findServerSettings(args);
+ args = verifyImplicitOption(args);
+ // Find the source root directories, and add the -src option before these, if not there already.
+ args = addSrcBeforeDirectories(args);
+ // Check that there is at least one -src supplied.
+ checkSrcOption(args);
+ // Check that there is one -d supplied.
+ bin_dir = findDirectoryOption(args,"-d","output", true, false, true);
+ gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true);
+ header_dir = findDirectoryOption(args,"-h","headers", false, false, true);
+ makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false);
+
+ // Load the prev build state database.
+ javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir,
+ findBooleanOption(args, "--permit-unidentified-artifacts"), out, err);
+
+ // Setup the suffix rules from the command line.
+ suffix_rules = javac_state.getJavaSuffixRule();
+ findTranslateOptions(args, suffix_rules);
+ if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) {
+ Log.error("You have translators but no gensrc dir (-s) specified!");
+ return -1;
+ }
+ findCopyOptions(args, suffix_rules);
+
+ // All found modules are put here.
+ Map<String,Module> modules = new HashMap<String,Module>();
+ // We start out in the legacy empty no-name module.
+ // As soon as we stumble on a module-info.java file we change to that module.
+ Module current_module = new Module("", "");
+ modules.put("", current_module);
+
+ // Find all sources, use the suffix rules to know which files are sources.
+ Map<String,Source> sources = new HashMap<String,Source>();
+ // Find the files, this will automatically populate the found modules
+ // with found packages where the sources are found!
+ findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false);
+
+ if (sources.isEmpty()) {
+ Log.error("Found nothing to compile!");
+ return -1;
+ }
+
+ // Find all source files allowable for linking.
+ // We might find more modules here as well.
+ Map<String,Source> sources_to_link_to = new HashMap<String,Source>();
+ // Always reuse -src for linking as well! This means that we might
+ // get two -sourcepath on the commandline after the rewrite, which is
+ // fine. We can have as many as we like. You need to have separate -src/-sourcepath/-classpath
+ // if you need different filtering rules for different roots. If you have the same filtering
+ // rules for all sourcepath roots, you can concatenate them using :(;) as before.
+ rewriteOptions(args, "-src", "-sourcepath");
+ findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true);
+
+ // Find all class files allowable for linking.
+ // And pickup knowledge of all modules found here.
+ // This cannot currently filter classes inside jar files.
+ Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
+// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
+
+ // Find all module sources allowable for linking.
+ Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
+ // findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
+
+ // Add the set of sources to the build database.
+ javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+ javac_state.now().checkInternalState("checking sources", false, sources);
+ javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+ javac_state.setVisibleSources(sources_to_link_to);
+
+ // If there is any change in the source files, taint packages
+ // and mark the database in need of saving.
+ javac_state.checkSourceStatus(false);
+
+ // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+ // in javac_state, simply because loading of the JavacState will clean out all artifacts
+ // that do not match the javac_state database.
+ javac_state.findAllArtifacts();
+
+ // Remove unidentified artifacts from the bin, gensrc and header dirs.
+ // (Unless we allow them to be there.)
+ // I.e. artifacts that are not known according to the build database (javac_state).
+ // For examples, files that have been manually copied into these dirs.
+ // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+ // in javac_state) have already been removed when the javac_state was loaded.
+ if (!findBooleanOption(args, "--permit-unidentified-artifacts")) {
+ javac_state.removeUnidentifiedArtifacts();
+ }
+ // Go through all sources and taint all packages that miss artifacts.
+ javac_state.taintPackagesThatMissArtifacts();
+
+ // Now clean out all known artifacts belonging to tainted packages.
+ javac_state.deleteClassArtifactsInTaintedPackages();
+ // Copy files, for example property files, images files, xml files etc etc.
+ javac_state.performCopying(bin_dir, suffix_rules);
+ // Translate files, for example compile properties or compile idls.
+ javac_state.performTranslation(gensrc_dir, suffix_rules);
+ // Add any potentially generated java sources to the tobe compiled list.
+ // (Generated sources must always have a package.)
+ Map<String,Source> generated_sources = new HashMap<String,Source>();
+ Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null,
+ generated_sources, modules, current_module, false, true, false);
+ javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+ // Recheck the the source files and their timestamps again.
+ javac_state.checkSourceStatus(true);
+
+ // Now do a safety check that the list of source files is identical
+ // to the list Make believes we are compiling. If we do not get this
+ // right, then incremental builds will fail with subtility.
+ // If any difference is detected, then we will fail hard here.
+ // This is an important safety net.
+ javac_state.compareWithMakefileList(makefile_source_list);
+
+ // Do the compilations, repeatedly until no tainted packages exist.
+ boolean again;
+ // Collect the name of all compiled packages.
+ Set<String> recently_compiled = new HashSet<String>();
+ boolean[] rc = new boolean[1];
+ do {
+ // Clean out artifacts in tainted packages.
+ javac_state.deleteClassArtifactsInTaintedPackages();
+ again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc);
+ if (!rc[0]) break;
+ } while (again);
+ // Only update the state if the compile went well.
+ if (rc[0]) {
+ javac_state.save();
+ // Collect all the artifacts.
+ javac_state.now().collectArtifacts(modules);
+ // Remove artifacts that were generated during the last compile, but not this one.
+ javac_state.removeSuperfluousArtifacts(recently_compiled);
+ }
+ return rc[0] ? 0 : -1;
+ } catch (ProblemException e) {
+ Log.error(e.getMessage());
+ return -1;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ /**
+ * Are java source files passed on the command line?
+ */
+ private boolean findJavaSourceFiles(String[] args) {
+ String prev = "";
+ for (String s : args) {
+ if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) {
+ return true;
+ }
+ prev = s;
+ }
+ return false;
+ }
+
+ /**
+ * Is an at file passed on the command line?
+ */
+ private boolean findAtFile(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("@")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Find the log level setting.
+ */
+ private String findLogLevel(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("--log=") && s.length()>6) {
+ return s.substring(6);
+ }
+ if (s.equals("-verbose")) {
+ return "info";
+ }
+ }
+ return "info";
+ }
+
+ /**
+ * Remove smart javac wrapper arguments, before feeding
+ * the args to the plain javac.
+ */
+ static String[] removeWrapperArgs(String[] args) {
+ String[] out = new String[args.length];
+ // The first source path index is remembered
+ // here. So that all following can be concatenated to it.
+ int source_path = -1;
+ // The same for class path.
+ int class_path = -1;
+ // And module path.
+ int module_path = -1;
+ int j = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-src") ||
+ args[i].equals("-x") ||
+ args[i].equals("-i") ||
+ args[i].equals("-xf") ||
+ args[i].equals("-if") ||
+ args[i].equals("-copy") ||
+ args[i].equals("-tr") ||
+ args[i].equals("-j")) {
+ // Just skip it and skip following value
+ i++;
+ } else if (args[i].startsWith("--server:")) {
+ // Just skip it.
+ } else if (args[i].startsWith("--log=")) {
+ // Just skip it.
+ } else if (args[i].equals("--permit-unidentified-artifacts")) {
+ // Just skip it.
+ } else if (args[i].equals("--permit-sources-without-package")) {
+ // Just skip it.
+ } else if (args[i].equals("--compare-found-sources")) {
+ // Just skip it and skip verify file name
+ i++;
+ } else if (args[i].equals("-sourcepath")) {
+ if (source_path == -1) {
+ source_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[source_path+1] = out[source_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else if (args[i].equals("-classpath")) {
+ if (class_path == -1) {
+ class_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[class_path+1] = out[class_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else if (args[i].equals("-modulepath")) {
+ if (module_path == -1) {
+ module_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[module_path+1] = out[module_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else {
+ // Copy argument.
+ out[j] = args[i];
+ j++;
+ }
+ }
+ String[] ret = new String[j];
+ System.arraycopy(out, 0, ret, 0, j);
+ return ret;
+ }
+
+ /**
+ * Make sure directory exist, create it if not.
+ */
+ private static boolean makeSureExists(File dir) {
+ // Make sure the dest directories exist.
+ if (!dir.exists()) {
+ if (!dir.mkdirs()) {
+ Log.error("Could not create the directory "+dir.getPath());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Verify that a package pattern is valid.
+ */
+ private static void checkPattern(String s) throws ProblemException {
+ // Package names like foo.bar.gamma are allowed, and
+ // package names suffixed with .* like foo.bar.* are
+ // also allowed.
+ Pattern p = Pattern.compile("[a-zA-Z_]{1}[a-zA-Z0-9_]*(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)*(\\.\\*)?+");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper package name pattern.");
+ }
+ }
+
+ /**
+ * Verify that a translate pattern is valid.
+ */
+ private static void checkTranslatePattern(String s) throws ProblemException {
+ // .prop=com.sun.tools.javac.smart.CompileProperties
+ // .idl=com.sun.corba.CompileIdl
+ // .g3=antlr.CompileGrammar,debug=true
+ Pattern p = Pattern.compile(
+ "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*=[a-z_]{1}[a-z0-9_]*(\\.[a-z_]{1}[a-z0-9_]*)*"+
+ "(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)(,.*)?");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper translate pattern.");
+ }
+ }
+
+ /**
+ * Verify that a copy pattern is valid.
+ */
+ private static void checkCopyPattern(String s) throws ProblemException {
+ // .gif
+ // .html
+ Pattern p = Pattern.compile(
+ "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper suffix.");
+ }
+ }
+
+ /**
+ * Verify that a source file name is valid.
+ */
+ private static void checkFilePattern(String s) throws ProblemException {
+ // File names like foo/bar/gamma/Bar.java are allowed,
+ // as well as /bar/jndi.properties as well as,
+ // */bar/Foo.java
+ Pattern p = null;
+ if (File.separatorChar == '\\') {
+ p = Pattern.compile("\\*?(.+\\\\)*.+");
+ }
+ else if (File.separatorChar == '/') {
+ p = Pattern.compile("\\*?(.+/)*.+");
+ } else {
+ throw new ProblemException("This platform uses the unsupported "+File.separatorChar+
+ " as file separator character. Please add support for it!");
+ }
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper file name.");
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option is used.
+ */
+ private static boolean hasOption(String[] args, String option) {
+ for (String a : args) {
+ if (a.equals(option)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if -implicit is supplied, if so check that it is none.
+ * If -implicit is not supplied, supply -implicit:none
+ * Only implicit:none is allowed because otherwise the multicore compilations
+ * and dependency tracking will be tangled up.
+ */
+ private static String[] verifyImplicitOption(String[] args)
+ throws ProblemException {
+
+ boolean foundImplicit = false;
+ for (String a : args) {
+ if (a.startsWith("-implicit:")) {
+ foundImplicit = true;
+ if (!a.equals("-implicit:none")) {
+ throw new ProblemException("The only allowed setting for sjavac is -implicit:none, it is also the default.");
+ }
+ }
+ }
+ if (foundImplicit) {
+ return args;
+ }
+ // -implicit:none not found lets add it.
+ String[] newargs = new String[args.length+1];
+ System.arraycopy(args,0, newargs, 0, args.length);
+ newargs[args.length] = "-implicit:none";
+ return newargs;
+ }
+
+ /**
+ * Rewrite a single option into something else.
+ */
+ private static void rewriteOptions(String[] args, String option, String new_option) {
+ for (int i=0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ args[i] = new_option;
+ }
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a directory.
+ * Create the directory if necessary.
+ */
+ private static File findDirectoryOption(String[] args, String option, String name, boolean needed, boolean allow_dups, boolean create)
+ throws ProblemException, ProblemException {
+ File dir = null;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (dir != null) {
+ throw new ProblemException("You have already specified the "+name+" dir!");
+ }
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following "+option+".");
+ }
+ if (args[i+1].indexOf(File.pathSeparatorChar) != -1) {
+ throw new ProblemException("You must only specify a single directory for "+option+".");
+ }
+ dir = new File(args[i+1]);
+ if (!dir.exists()) {
+ if (!create) {
+ throw new ProblemException("This directory does not exist: "+dir.getPath());
+ } else
+ if (!makeSureExists(dir)) {
+ throw new ProblemException("Cannot create directory "+dir.getPath());
+ }
+ }
+ if (!dir.isDirectory()) {
+ throw new ProblemException("\""+args[i+1]+"\" is not a directory.");
+ }
+ }
+ }
+ if (dir == null && needed) {
+ throw new ProblemException("You have to specify "+option);
+ }
+ try {
+ if (dir != null)
+ return dir.getCanonicalFile();
+ } catch (IOException e) {
+ throw new ProblemException(""+e);
+ }
+ return null;
+ }
+
+ /**
+ * Option is followed by path.
+ */
+ private static boolean shouldBeFollowedByPath(String o) {
+ return o.equals("-s") ||
+ o.equals("-h") ||
+ o.equals("-d") ||
+ o.equals("-sourcepath") ||
+ o.equals("-classpath") ||
+ o.equals("-bootclasspath") ||
+ o.equals("-src");
+ }
+
+ /**
+ * Add -src before source root directories if not already there.
+ */
+ private static String[] addSrcBeforeDirectories(String[] args) {
+ List<String> newargs = new ArrayList<String>();
+ for (int i = 0; i<args.length; ++i) {
+ File dir = new File(args[i]);
+ if (dir.exists() && dir.isDirectory()) {
+ if (i == 0 || !shouldBeFollowedByPath(args[i-1])) {
+ newargs.add("-src");
+ }
+ }
+ newargs.add(args[i]);
+ }
+ return newargs.toArray(new String[0]);
+ }
+
+ /**
+ * Check the -src options.
+ */
+ private static void checkSrcOption(String[] args)
+ throws ProblemException {
+ Set<File> dirs = new HashSet<File>();
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-src")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following -src.");
+ }
+ StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator);
+ while (st.hasMoreElements()) {
+ File dir = new File(st.nextToken());
+ if (!dir.exists()) {
+ throw new ProblemException("This directory does not exist: "+dir.getPath());
+ }
+ if (!dir.isDirectory()) {
+ throw new ProblemException("\""+dir.getPath()+"\" is not a directory.");
+ }
+ if (dirs.contains(dir)) {
+ throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!");
+ }
+ dirs.add(dir);
+ }
+ }
+ }
+ if (dirs.isEmpty()) {
+ throw new ProblemException("You have to specify -src.");
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a file.
+ */
+ private static File findFileOption(String[] args, String option, String name, boolean needed)
+ throws ProblemException, ProblemException {
+ File file = null;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (file != null) {
+ throw new ProblemException("You have already specified the "+name+" file!");
+ }
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following "+option+".");
+ }
+ file = new File(args[i+1]);
+ if (file.isDirectory()) {
+ throw new ProblemException("\""+args[i+1]+"\" is not a file.");
+ }
+ if (!file.exists() && needed) {
+ throw new ProblemException("The file \""+args[i+1]+"\" does not exist.");
+ }
+
+ }
+ }
+ if (file == null && needed) {
+ throw new ProblemException("You have to specify "+option);
+ }
+ return file;
+ }
+
+ /**
+ * Look for a specific switch, return true if found.
+ */
+ public static boolean findBooleanOption(String[] args, String option) {
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a number.
+ */
+ public static int findNumberOption(String[] args, String option) {
+ int rc = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (args.length > i+1) {
+ rc = Integer.parseInt(args[i+1]);
+ }
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Scan the arguments to find the option (-tr) that setup translation rules to java source
+ * from different sources. For example: .properties are translated using CompileProperties
+ * The found translators are stored as suffix rules.
+ */
+ private static void findTranslateOptions(String[] args, Map<String,Transformer> suffix_rules)
+ throws ProblemException, ProblemException {
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-tr")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a translate rule following -tr.");
+ }
+ String s = args[i+1];
+ checkTranslatePattern(s);
+ int ep = s.indexOf("=");
+ String suffix = s.substring(0,ep);
+ String classname = s.substring(ep+1);
+ if (suffix_rules.get(suffix) != null) {
+ throw new ProblemException("You have already specified a "+
+ "rule for the suffix "+suffix);
+ }
+ if (s.equals(".class")) {
+ throw new ProblemException("You cannot have a translator for .class files!");
+ }
+ if (s.equals(".java")) {
+ throw new ProblemException("You cannot have a translator for .java files!");
+ }
+ String extra = null;
+ int exp = classname.indexOf(",");
+ if (exp != -1) {
+ extra = classname.substring(exp+1);
+ classname = classname.substring(0,exp);
+ }
+ try {
+ Class<?> cl = Class.forName(classname);
+ Transformer t = (Transformer)cl.newInstance();
+ t.setExtra(extra);
+ suffix_rules.put(suffix, t);
+ }
+ catch (Exception e) {
+ throw new ProblemException("Cannot use "+classname+" as a translator!");
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir.
+ * For example: -copy .html
+ * The found copiers are stored as suffix rules as well. No translation is done, just copying.
+ */
+ private void findCopyOptions(String[] args, Map<String,Transformer> suffix_rules)
+ throws ProblemException, ProblemException {
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-copy")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a translate rule following -tr.");
+ }
+ String s = args[i+1];
+ checkCopyPattern(s);
+ if (suffix_rules.get(s) != null) {
+ throw new ProblemException("You have already specified a "+
+ "rule for the suffix "+s);
+ }
+ if (s.equals(".class")) {
+ throw new ProblemException("You cannot have a copy rule for .class files!");
+ }
+ if (s.equals(".java")) {
+ throw new ProblemException("You cannot have a copy rule for .java files!");
+ }
+ suffix_rules.put(s, javac_state.getCopier());
+ }
+ }
+ }
+
+ /**
+ * Rewrite a / separated path into \ separated, but only
+ * if we are running on a platform were File.separatorChar=='\', ie winapi.
+ */
+ private String fixupSeparator(String p) {
+ if (File.separatorChar == '/') return p;
+ return p.replaceAll("/", "\\\\");
+ }
+
+ /**
+ * Scan the arguments for -i -x -xf -if followed by the option
+ * -src, -sourcepath, -modulepath or -classpath and produce a map of all the
+ * files to referenced for that particular option.
+ *
+ * Store the found sources and the found modules in the supplied maps.
+ */
+ private boolean findFiles(String[] args, String option, Set<String> suffixes,
+ Map<String,Source> found_files, Map<String, Module> found_modules,
+ Module current_module, boolean inLinksrc)
+ throws ProblemException, ProblemException
+ {
+ // Track which source roots, source path roots and class path roots have been added.
+ Set<File> roots = new HashSet<File>();
+ // Track the current set of package includes,excludes as well as excluded source files,
+ // to be used in the next -src/-sourcepath/-classpath
+ List<String> includes = new LinkedList<String>();
+ List<String> excludes = new LinkedList<String>();
+ List<String> excludefiles = new LinkedList<String>();
+ List<String> includefiles = new LinkedList<String>();
+ // This include is used to find all modules in the source.
+ List<String> moduleinfo = new LinkedList<String>();
+ moduleinfo.add("module-info.java");
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-i")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a package pattern following -i");
+ }
+ String incl = args[i+1];
+ checkPattern(incl);
+ includes.add(incl);
+ }
+ if (args[i].equals("-x")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a package pattern following -x");
+ }
+ String excl = args[i+1];
+ checkPattern(excl);
+ excludes.add(excl);
+ }
+ if (args[i].equals("-xf")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following -xf");
+ }
+ String exclf = args[i+1];
+ checkFilePattern(exclf);
+ exclf = Util.normalizeDriveLetter(exclf);
+ excludefiles.add(fixupSeparator(exclf));
+ }
+ if (args[i].equals("-if")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following -xf");
+ }
+ String inclf = args[i+1];
+ checkFilePattern(inclf);
+ inclf = Util.normalizeDriveLetter(inclf);
+ includefiles.add(fixupSeparator(inclf));
+ }
+ if (args[i].equals(option)) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following "+option);
+ }
+ String[] root_dirs = args[i+1].split(File.pathSeparator);
+ for (String r : root_dirs) {
+ File root = new File(r);
+ if (!root.isDirectory()) {
+ throw new ProblemException("\""+r+"\" is not a directory.");
+ }
+ try {
+ root = root.getCanonicalFile();
+ } catch (IOException e) {
+ throw new ProblemException(""+e);
+ }
+ if (roots.contains(root)) {
+ throw new ProblemException("\""+r+"\" has already been used for "+option);
+ }
+ if (roots.equals(bin_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d");
+ }
+ if (roots.equals(gensrc_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s");
+ }
+ if (roots.equals(header_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h");
+ }
+ roots.add(root);
+ Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles,
+ found_files, found_modules, current_module,
+ findBooleanOption(args, "--permit-sources-without-package"),
+ false, inLinksrc);
+ }
+ }
+ if (args[i].equals("-src") ||
+ args[i].equals("-sourcepath") ||
+ args[i].equals("-modulepath") ||
+ args[i].equals("-classpath"))
+ {
+ // Reset the includes,excludes and excludefiles after they have been used.
+ includes = new LinkedList<String>();
+ excludes = new LinkedList<String>();
+ excludefiles = new LinkedList<String>();
+ includefiles = new LinkedList<String>();
+ }
+ }
+ return true;
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Module.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The module is the root of a set of packages/sources/artifacts.
+ * At the moment there is only one module in use, the empty/no-name/default module.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Module implements Comparable<Module> {
+ private String name;
+ private String dirname;
+ private Map<String,Package> packages = new HashMap<String,Package>();
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ private Map<String,File> artifacts = new HashMap<String,File>();
+
+ public Module(String n, String dn) {
+ name = n;
+ dirname = n;
+ }
+
+ public String name() { return name; }
+ public String dirname() { return dirname; }
+ public Map<String,Package> packages() { return packages; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Module) && name.equals(((Module)o).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public int compareTo(Module o) {
+ return name.compareTo(o.name);
+ }
+
+ public void save(StringBuilder b) {
+ b.append("M ").append(name).append(":").append("\n");
+ Package.savePackages(packages, b);
+ }
+
+ public static Module load(String l) {
+ int cp = l.indexOf(':',2);
+ if (cp == -1) return null;
+ String name = l.substring(2,cp);
+ return new Module(name, "");
+ }
+
+ public static void saveModules(Map<String,Module> ms, StringBuilder b)
+ {
+ for (Module m : ms.values()) {
+ m.save(b);
+ }
+ }
+
+ public void addPackage(Package p) {
+ packages.put(p.name(), p);
+ }
+
+ public Package lookupPackage(String pkg) {
+ Package p = packages.get(pkg);
+ if (p == null) {
+ p = new Package(this, pkg);
+ packages.put(pkg, p);
+ }
+ return p;
+ }
+
+ public void addSource(String pkg, Source src) {
+ Package p = lookupPackage(pkg);
+ src.setPackage(p);
+ p.addSource(src);
+ sources.put(src.file().getPath(), src);
+ }
+
+ public Source lookupSource(String path) {
+ return sources.get(path);
+ }
+
+ public void addArtifacts(String pkg, Set<URI> as) {
+ Package p = lookupPackage(pkg);
+ for (URI u : as) {
+ p.addArtifact(new File(u));
+ }
+ }
+
+ public void setDependencies(String pkg, Set<String> deps) {
+ Package p = lookupPackage(pkg);
+ p.setDependencies(deps);
+ }
+
+ public void setPubapi(String pkg, List<String> ps) {
+ Package p = lookupPackage(pkg);
+ p.setPubapi(ps);
+ }
+
+ public boolean hasPubapiChanged(String pkg, List<String> ps) {
+ Package p = lookupPackage(pkg);
+ return p.hasPubapiChanged(ps);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Package.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The Package class maintains meta information about a package.
+ * For example its sources, dependents,its pubapi and its artifacts.
+ *
+ * It might look odd that we track dependents/pubapi/artifacts on
+ * a package level, but it makes sense since recompiling a full package
+ * takes as long as recompiling a single java file in that package,
+ * if you take into account the startup time of the jvm.
+ *
+ * Also the dependency information will be much smaller (good for the javac_state file size)
+ * and it simplifies tracking artifact generation, you do not always know from which
+ * source a class file was generated, but you always know which package it belongs to.
+ *
+ * It is also educational to see package dependencies triggering recompilation of
+ * other packages. Even though the recompilation was perhaps not necessary,
+ * the visible recompilation of the dependent packages indicates how much circular
+ * dependencies your code has.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Package implements Comparable<Package> {
+ // The module this package belongs to. (There is a legacy module with an empty string name,
+ // used for all legacy sources.)
+ private Module mod;
+ // Name of this package, module:pkg
+ // ex1 jdk.base:java.lang
+ // ex2 :java.lang (when in legacy mode)
+ private String name;
+ // The directory path to the package. If the package belongs to a module,
+ // then that module's file system name is part of the path.
+ private String dirname;
+ // This package depends on these packages.
+ private Set<String> dependencies = new HashSet<String>();
+ // This package has the following dependents, that depend on this package.
+ private Set<String> dependents = new HashSet<String>();
+ // This is the public api of this package.
+ private List<String> pubapi = new ArrayList<String>();
+ // Map from source file name to Source info object.
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ // This package generated these artifacts.
+ private Map<String,File> artifacts = new HashMap<String,File>();
+
+ public Package(Module m, String n) {
+ int c = n.indexOf(":");
+ assert(c != -1);
+ String mn = n.substring(0,c);
+ assert(m.name().equals(m.name()));
+ name = n;
+ dirname = n.replace('.', File.separatorChar);
+ if (m.name().length() > 0) {
+ // There is a module here, prefix the module dir name to the path.
+ dirname = m.dirname()+File.separatorChar+dirname;
+ }
+ }
+
+ public Module mod() { return mod; }
+ public String name() { return name; }
+ public String dirname() { return dirname; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+ public List<String> pubapi() { return pubapi; }
+
+ public Set<String> dependencies() { return dependencies; }
+ public Set<String> dependents() { return dependents; }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Package) && name.equals(((Package)o).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public int compareTo(Package o) {
+ return name.compareTo(o.name);
+ }
+
+ public void addSource(Source s) {
+ sources.put(s.file().getPath(), s);
+ }
+
+ public void addDependency(String d) {
+ dependencies.add(d);
+ }
+
+ public void addDependent(String d) {
+ dependents.add(d);
+ }
+
+ public void addPubapi(String p) {
+ pubapi.add(p);
+ }
+
+ /**
+ * Check if we have knowledge in the javac state that
+ * describe the results of compiling this package before.
+ */
+ public boolean existsInJavacState() {
+ return artifacts.size() > 0 || pubapi.size() > 0;
+ }
+
+ public static List<String> pubapiToList(String ps)
+ {
+ String[] lines = ps.split("\n");
+ List<String> r = new ArrayList<String>();
+ for (String l : lines) {
+ r.add(l);
+ }
+ return r;
+ }
+
+ public boolean hasPubapiChanged(List<String> ps) {
+ Iterator<String> i = ps.iterator();
+ Iterator<String> j = pubapi.iterator();
+ int line = 0;
+ while (i.hasNext() && j.hasNext()) {
+ String is = i.next();
+ String js = j.next();
+ if (!is.equals(js)) {
+ Log.debug("Change in pubapi for package "+name+" line "+line);
+ Log.debug("Old: "+js);
+ Log.debug("New: "+is);
+ return true;
+ }
+ line++;
+ }
+ if ((i.hasNext() && !j.hasNext() ) ||
+ (!i.hasNext() && j.hasNext())) {
+ Log.debug("Change in pubapi for package "+name);
+ if (i.hasNext()) {
+ Log.debug("New has more lines!");
+ } else {
+ Log.debug("Old has more lines!");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void setPubapi(List<String> ps) {
+ pubapi = ps;
+ }
+
+ public void setDependencies(Set<String> ds) {
+ dependencies = ds;
+ }
+
+ public void save(StringBuilder b) {
+ b.append("P ").append(name).append("\n");
+ Source.saveSources(sources, b);
+ saveDependencies(b);
+ savePubapi(b);
+ saveArtifacts(b);
+ }
+
+ static public Package load(Module module, String l) {
+ String name = l.substring(2);
+ return new Package(module, name);
+ }
+
+ public void loadDependency(String l) {
+ String n = l.substring(2);
+ addDependency(n);
+ }
+
+ public void loadPubapi(String l) {
+ String pi = l.substring(2);
+ addPubapi(pi);
+ }
+
+ public void saveDependencies(StringBuilder b) {
+ List<String> sorted_dependencies = new ArrayList<String>();
+ for (String key : dependencies) {
+ sorted_dependencies.add(key);
+ }
+ Collections.sort(sorted_dependencies);
+ for (String a : sorted_dependencies) {
+ b.append("D "+a+"\n");
+ }
+ }
+
+ public void savePubapi(StringBuilder b) {
+ for (String l : pubapi) {
+ b.append("I "+l+"\n");
+ }
+ }
+
+ public static void savePackages(Map<String,Package> packages, StringBuilder b) {
+ List<String> sorted_packages = new ArrayList<String>();
+ for (String key : packages.keySet() ) {
+ sorted_packages.add(key);
+ }
+ Collections.sort(sorted_packages);
+ for (String s : sorted_packages) {
+ Package p = packages.get(s);
+ p.save(b);
+ }
+ }
+
+ public void addArtifact(String a) {
+ artifacts.put(a, new File(a));
+ }
+
+ public void addArtifact(File f) {
+ artifacts.put(f.getPath(), f);
+ }
+
+ public void addArtifacts(Set<URI> as) {
+ for (URI u : as) {
+ addArtifact(new File(u));
+ }
+ }
+
+ public void setArtifacts(Set<URI> as) {
+ assert(!artifacts.isEmpty());
+ artifacts = new HashMap<String,File>();
+ addArtifacts(as);
+ }
+
+ public void loadArtifact(String l) {
+ // Find next space after "A ".
+ int dp = l.indexOf(' ',2);
+ String fn = l.substring(2,dp);
+ long last_modified = Long.parseLong(l.substring(dp+1));
+ File f = new File(fn);
+ if (f.exists() && f.lastModified() != last_modified) {
+ // Hmm, the artifact on disk does not have the same last modified
+ // timestamp as the information from the build database.
+ // We no longer trust the artifact on disk. Delete it.
+ // The smart javac wrapper will then rebuild the artifact.
+ Log.debug("Removing "+f.getPath()+" since its timestamp does not match javac_state.");
+ f.delete();
+ }
+ artifacts.put(f.getPath(), f);
+ }
+
+ public void saveArtifacts(StringBuilder b) {
+ List<File> sorted_artifacts = new ArrayList<File>();
+ for (File f : artifacts.values()) {
+ sorted_artifacts.add(f);
+ }
+ Collections.sort(sorted_artifacts);
+ for (File f : sorted_artifacts) {
+ // The last modified information is only used
+ // to detect tampering with the output dir.
+ // If the outputdir has been modified, not by javac,
+ // then a mismatch will be detected in the last modified
+ // timestamps stored in the build database compared
+ // to the timestamps on disk and the artifact will be deleted.
+
+ b.append("A "+f.getPath()+" "+f.lastModified()+"\n");
+ }
+ }
+
+ /**
+ * Always clean out a tainted package before it is recompiled.
+ */
+ public void deleteArtifacts() {
+ for (File a : artifacts.values()) {
+ a.delete();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/ProblemException.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+/**
+ * Used to signal serious problems when running sjavac.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class ProblemException extends Exception {
+ static final long serialVersionUID = -3387516993124229949L;
+ public ProblemException(String s) {
+ super(s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Set;
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/** A Source object maintains information about a source file.
+ * For example which package it belongs to and kind of source it is.
+ * The class also knows how to find source files (scanRoot) given include/exclude
+ * patterns and a root.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Source implements Comparable<Source> {
+ // The package the source belongs to.
+ private Package pkg;
+ // Name of this source file, relative its source root.
+ // For example: java/lang/Object.java
+ // Or if the source file is inside a module:
+ // jdk.base/java/lang/Object.java
+ private String name;
+ // What kind of file is this.
+ private String suffix;
+ // When this source file was last_modified
+ private long lastModified;
+ // The source File.
+ private File file;
+ // The source root under which file resides.
+ private File root;
+ // If the source is generated.
+ private boolean isGenerated;
+ // If the source is only linked to, not compiled.
+ private boolean linkedOnly;
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Source) && name.equals(((Source)o).name);
+ }
+
+ @Override
+ public int compareTo(Source o) {
+ return name.compareTo(o.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public Source(Module m, String n, File f, File r) {
+ name = n;
+ int dp = n.lastIndexOf(".");
+ if (dp != -1) {
+ suffix = n.substring(dp);
+ } else {
+ suffix = "";
+ }
+ file = f;
+ root = r;
+ lastModified = f.lastModified();
+ linkedOnly = false;
+ }
+
+ public Source(Package p, String n, long lm) {
+ pkg = p;
+ name = n;
+ int dp = n.lastIndexOf(".");
+ if (dp != -1) {
+ suffix = n.substring(dp);
+ } else {
+ suffix = "";
+ }
+ file = null;
+ root = null;
+ lastModified = lm;
+ linkedOnly = false;
+ int ls = n.lastIndexOf('/');
+ }
+
+ public String name() { return name; }
+ public String suffix() { return suffix; }
+ public Package pkg() { return pkg; }
+ public File file() { return file; }
+ public File root() { return root; }
+ public long lastModified() {
+ return lastModified;
+ }
+
+ public void setPackage(Package p) {
+ pkg = p;
+ }
+
+ public void markAsGenerated() {
+ isGenerated = true;
+ }
+
+ public boolean isGenerated() {
+ return isGenerated;
+ }
+
+ public void markAsLinkedOnly() {
+ linkedOnly = true;
+ }
+
+ public boolean isLinkedOnly() {
+ return linkedOnly;
+ }
+
+ private void save(StringBuilder b) {
+ String CL = linkedOnly?"L":"C";
+ String GS = isGenerated?"G":"S";
+ b.append(GS+" "+CL+" "+name+" "+file.lastModified()+"\n");
+ }
+ // Parse a line that looks like this:
+ // S C /code/alfa/A.java 1357631228000
+ static public Source load(Package lastPackage, String l, boolean isGenerated) {
+ int sp = l.indexOf(' ',4);
+ if (sp == -1) return null;
+ String name = l.substring(4,sp);
+ long last_modified = Long.parseLong(l.substring(sp+1));
+
+ boolean isLinkedOnly = false;
+ if (l.charAt(2) == 'L') {
+ isLinkedOnly = true;
+ } else if (l.charAt(2) == 'C') {
+ isLinkedOnly = false;
+ } else return null;
+
+ Source s = new Source(lastPackage, name, last_modified);
+ s.file = new File(name);
+ if (isGenerated) s.markAsGenerated();
+ if (isLinkedOnly) s.markAsLinkedOnly();
+ return s;
+ }
+
+ public static void saveSources(Map<String,Source> sources, StringBuilder b) {
+ List<String> sorted_sources = new ArrayList<String>();
+ for (String key : sources.keySet()) {
+ sorted_sources.add(key);
+ }
+ Collections.sort(sorted_sources);
+ for (String key : sorted_sources) {
+ Source s = sources.get(key);
+ s.save(b);
+ }
+ }
+
+ /**
+ * Recurse into the directory root and find all files matchine the excl/incl/exclfiles/inclfiles rules.
+ * Detects the existence of module-info.java files and presumes that the directory it resides in
+ * is the name of the current module.
+ */
+ static public void scanRoot(File root,
+ Set<String> suffixes,
+ List<String> excludes, List<String> includes,
+ List<String> excludeFiles, List<String> includeFiles,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule,
+ boolean permitSourcesWithoutPackage,
+ boolean inGensrc,
+ boolean inLinksrc)
+ throws ProblemException {
+
+ if (root == null) return;
+ int root_prefix = root.getPath().length()+1;
+ // This is the root source directory, it must not contain any Java sources files
+ // because we do not allow Java source files without a package.
+ // (Unless of course --permit-sources-without-package has been specified.)
+ // It might contain other source files however, (for -tr and -copy) these will
+ // always be included, since no package pattern can match the root directory.
+ currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
+ excludeFiles, includeFiles, false,
+ foundFiles, foundModules, currentModule,
+ inGensrc, inLinksrc);
+
+ File[] dirfiles = root.listFiles();
+ for (File d : dirfiles) {
+ if (d.isDirectory()) {
+ // Descend into the directory structure.
+ scanDirectory(d, root_prefix, root, suffixes,
+ excludes, includes, excludeFiles, includeFiles,
+ false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+ }
+ }
+
+ /**
+ * Test if a path matches any of the patterns given.
+ * The pattern foo.bar matches only foo.bar
+ * The pattern foo.* matches foo.bar and foo.bar.zoo etc
+ */
+ static private boolean hasMatch(String path, List<String> patterns) {
+ for (String p : patterns) {
+ // Exact match
+ if (p.equals(path)) {
+ return true;
+ }
+ // Single dot the end matches this package and all its subpackages.
+ if (p.endsWith(".*")) {
+ // Remove the wildcard
+ String patprefix = p.substring(0,p.length()-2);
+ // Does the path start with the pattern prefix?
+ if (path.startsWith(patprefix)) {
+ // If the path has the same length as the pattern prefix, then it is a match.
+ // If the path is longer, then make sure that
+ // the next part of the path starts with a dot (.) to prevent
+ // wildcard matching in the middle of a package name.
+ if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Matches patterns with the asterisk first. */
+ // The pattern foo/bar.java only matches foo/bar.java
+ // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
+ static private boolean hasFileMatch(String path, List<String> patterns) {
+ path = Util.normalizeDriveLetter(path);
+ for (String p : patterns) {
+ // Exact match
+ if (p.equals(path)) {
+ return true;
+ }
+ // Single dot the end matches this package and all its subpackages.
+ if (p.startsWith("*")) {
+ // Remove the wildcard
+ String patsuffix = p.substring(1);
+ // Does the path start with the pattern prefix?
+ if (path.endsWith(patsuffix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add the files in the directory, assuming that the file has not been excluded.
+ * Returns a fresh Module object, if this was a dir with a module-info.java file.
+ */
+ static private Module addFilesInDir(File dir, int rootPrefix, File root,
+ Set<String> suffixes, boolean allow_javas,
+ List<String> excludeFiles, List<String> includeFiles, boolean all,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule,
+ boolean inGensrc,
+ boolean inLinksrc)
+ throws ProblemException
+ {
+ for (File f : dir.listFiles()) {
+ if (f.isFile()) {
+ boolean should_add =
+ (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
+ && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
+
+ if (should_add) {
+ if (!allow_javas && f.getName().endsWith(".java")) {
+ throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
+ ", please remove "+f.getName());
+ }
+ // Extract the file name relative the root.
+ String fn = f.getPath().substring(rootPrefix);
+ // Extract the package name.
+ int sp = fn.lastIndexOf(File.separatorChar);
+ String pkg = "";
+ if (sp != -1) {
+ pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
+ }
+ // Is this a module-info.java file?
+ if (fn.endsWith("module-info.java")) {
+ // Aha! We have recursed into a module!
+ if (!currentModule.name().equals("")) {
+ throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
+ }
+ String module_name = fn.substring(0,fn.length()-16);
+ currentModule = new Module(module_name, f.getPath());
+ foundModules.put(module_name, currentModule);
+ }
+ // Extract the suffix.
+ int dp = fn.lastIndexOf(".");
+ String suffix = "";
+ if (dp > 0) {
+ suffix = fn.substring(dp);
+ }
+ // Should the file be added?
+ if (all || suffixes.contains(suffix)) {
+ Source of = foundFiles.get(f.getPath());
+ if (of != null) {
+ throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
+ }
+ of = currentModule.lookupSource(f.getPath());
+ if (of != null) {
+ // Oups, the source is already added, could be ok, could be not, lets check.
+ if (inLinksrc) {
+ // So we are collecting sources for linking only.
+ if (of.isLinkedOnly()) {
+ // Ouch, this one is also for linking only. Bad.
+ throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
+ }
+ // Ok, the existing source is to be compiled. Thus this link only is redundant
+ // since all compiled are also linked to. Continue to the next source.
+ // But we need to add the source, so that it will be visible to linking,
+ // if not the multi core compile will fail because a JavaCompiler cannot
+ // find the necessary dependencies for its part of the source.
+ foundFiles.put(f.getPath(), of);
+ continue;
+ } else {
+ // We are looking for sources to compile, if we find an existing to be compiled
+ // source with the same name, it is an internal error, since we must
+ // find the sources to be compiled before we find the sources to be linked to.
+ throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
+ }
+ }
+ Source s = new Source(currentModule, f.getPath(), f, root);
+ if (inGensrc) s.markAsGenerated();
+ if (inLinksrc) {
+ s.markAsLinkedOnly();
+ }
+ pkg = currentModule.name()+":"+pkg;
+ foundFiles.put(f.getPath(), s);
+ currentModule.addSource(pkg, s);
+ }
+ }
+ }
+ }
+ return currentModule;
+ }
+
+ private static boolean gurka = false;
+
+ static private void scanDirectory(File dir, int rootPrefix, File root,
+ Set<String> suffixes,
+ List<String> excludes, List<String> includes,
+ List<String> excludeFiles, List<String> includeFiles, boolean all,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule, boolean inGensrc, boolean inLinksrc)
+ throws ProblemException {
+
+ String pkg_name = "";
+ // Remove the root prefix from the dir path, and replace file separator with dots
+ // to get the package name.
+ if (dir.getPath().length() > rootPrefix) {
+ pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.');
+ }
+ // Should this package directory be included and not excluded?
+ if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) &&
+ (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) {
+ // Add the source files.
+ currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all,
+ foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+
+ for (File d : dir.listFiles()) {
+ if (d.isDirectory()) {
+ // Descend into the directory structure.
+ scanDirectory(d, rootPrefix, root, suffixes,
+ excludes, includes, excludeFiles, includeFiles, all,
+ foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * The transform interface is used to transform content inside a package, from one form to another.
+ * Usually the output form is an unpredictable number of output files. (eg class files)
+ * but can also be an unpredictable number of generated source files (eg idl2java)
+ * or a single predictable output file (eg when copying,cleaning or compiling a properties file).
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public interface Transformer
+{
+ /**
+ * The transform method takes a set of package names, mapped to their source files and to the
+ * pubapis of the packages.
+ *
+ * The transform implementation must:
+ * store the names of the generated artifacts for each package into package_artifacts
+ * store found dependencies to other packages into the supplied set package_dependencies
+ * store the public api for a package into the supplied set package_pubapis
+ *
+ * Any benign messages as a result of running the transform
+ * are written into stdout, and errors are written to stderr.
+ *
+ * The debug_level can be 0=silent (only warnings and errors) 1=normal 2=verbose 3 or greater=debug
+ * setExtra is used to set the extra information information that can be passed on
+ * the command line to the smart javac wrapper.
+ *
+ * If sjavac is building incrementally from an existing javac_state, the var incremental is true.
+ *
+ * The transformer will only be called if some source in the package (or dependency) has
+ * a modified timestamp. Thus the transformer might get called with many sources, of which
+ * only one has changed. The transformer is allowed to regenerate all artifacts but
+ * a better transformer will only write those artifacts that need updating.
+ *
+ * However the transformer must verify that the existing artifacts really are there!
+ * and it must always update package_artifacts, package_dependencies, and package_pubapis correctly.
+ * This means that at least for Java source, it will always have to recompile the sources.
+ *
+ * The transformer is allowed to put files anywhere in the dest_root.
+ * An example of this is, can be the META-INF transformer that copy files
+ * below META-INF directories to the single META-INF directory below dest_root.
+ *
+ * False is returned if there was an error that prevented the transform.
+ * I.e. something was printed on stderr.
+ *
+ * If num_cores is set to a non-zero value. The transform should attempt to use no more than these
+ * number of threads for heavy work.
+ */
+ boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSources,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependencies,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err);
+
+ void setExtra(String e);
+ void setExtra(String[] args);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Utilities.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Util {
+
+ public static String toFileSystemPath(String pkgId) {
+ if (pkgId == null || pkgId.length()==0) return null;
+ String pn;
+ if (pkgId.charAt(0) == ':') {
+ // When the module is the default empty module.
+ // Do not prepend the module directory, because there is none.
+ // Thus :java.foo.bar translates to java/foo/bar (or \)
+ pn = pkgId.substring(1).replace('.',File.separatorChar);
+ } else {
+ // There is a module. Thus jdk.base:java.foo.bar translates
+ // into jdk.base/java/foo/bar
+ int cp = pkgId.indexOf(':');
+ String mn = pkgId.substring(0,cp);
+ pn = mn+File.separatorChar+pkgId.substring(cp+1).replace('.',File.separatorChar);
+ }
+ return pn;
+ }
+
+ public static String justPackageName(String pkgName) {
+ int c = pkgName.indexOf(":");
+ assert(c != -1);
+ return pkgName.substring(c+1);
+ }
+
+ public static String extractStringOption(String opName, String s) {
+ int p = s.indexOf(opName+"=");
+ if (p == -1) return null;
+ p+=opName.length()+1;
+ int pe = s.indexOf(',', p);
+ if (pe == -1) pe = s.length();
+ return s.substring(p, pe);
+ }
+
+ public static int extractIntOption(String opName, String s) {
+ int p = s.indexOf(opName+"=");
+ if (p == -1) return 0;
+ p+=opName.length()+1;
+ int pe = s.indexOf(',', p);
+ if (pe == -1) pe = s.length();
+ int v = 0;
+ try {
+ v = Integer.parseInt(s.substring(p, pe));
+ } catch (Exception e) {}
+ return v;
+ }
+
+ /**
+ * Clean out unwanted sub options supplied inside a primary option.
+ * For example to only had portfile remaining from:
+ * settings="--server:id=foo,portfile=bar"
+ * do settings = cleanOptions("--server:",Util.set("-portfile"),settings);
+ * now settings equals "--server:portfile=bar"
+ *
+ * @param optionPrefix The option name, including colon, eg --server:
+ * @param allowsSubOptions A set of the allowed sub options, id portfile etc.
+ * @param s The option settings string.
+ */
+ public static String cleanSubOptions(String optionPrefix, Set<String> allowedSubOptions, String s) {
+ StringBuilder sb = new StringBuilder();
+ if (!s.startsWith(optionPrefix)) return "";
+ StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ",");
+ while (st.hasMoreTokens()) {
+ String o = st.nextToken();
+ int p = o.indexOf('=');
+ if (p>0) {
+ String key = o.substring(0,p);
+ String val = o.substring(p+1);
+ if (allowedSubOptions.contains(key)) {
+ if (sb.length() > 0) sb.append(',');
+ sb.append(key+"="+val);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convenience method to create a set with strings.
+ */
+ public static Set<String> set(String... ss) {
+ Set<String> set = new HashSet<String>();
+ set.addAll(Arrays.asList(ss));
+ return set;
+ }
+
+ /**
+ * Normalize windows drive letter paths to upper case to enable string
+ * comparison.
+ *
+ * @param file File name to normalize
+ * @return The normalized string if file has a drive letter at the beginning,
+ * otherwise the original string.
+ */
+ public static String normalizeDriveLetter(String file) {
+ if (file.length() > 2 && file.charAt(1) == ':') {
+ return Character.toUpperCase(file.charAt(0)) + file.substring(1);
+ } else if (file.length() > 3 && file.charAt(0) == '*'
+ && file.charAt(2) == ':') {
+ // Handle a wildcard * at the beginning of the string.
+ return file.substring(0, 1) + Character.toUpperCase(file.charAt(1))
+ + file.substring(2);
+ }
+ return file;
+ }
+
+ /**
+ * Locate the setting for the server properties.
+ */
+ public static String findServerSettings(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("--server:")) {
+ return s;
+ }
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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.sjavac.comp;
+
+import javax.lang.model.element.Element;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+
+/** Utility class containing dependency information between packages
+ * and the pubapi for a package.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Dependencies {
+ protected static final Context.Key<Dependencies> dependenciesKey =
+ new Context.Key<Dependencies>();
+
+ // The log to be used for error reporting.
+ protected Log log;
+ // Map from package name to packages that the package depends upon.
+ protected Map<Name,Set<Name>> deps;
+ // This is the set of all packages that are supplied
+ // through the java files at the command line.
+ protected Set<Name> explicitPackages;
+
+ // Map from a package name to its public api.
+ // Will the Name encode the module in the future?
+ // If not, this will have to change to map from Module+Name to public api.
+ protected Map<Name,StringBuffer> publicApiPerClass;
+
+ public static Dependencies instance(Context context) {
+ Dependencies instance = context.get(dependenciesKey);
+ if (instance == null)
+ instance = new Dependencies(context);
+ return instance;
+ }
+
+ private Dependencies(Context context) {
+ context.put(dependenciesKey, this);
+ log = Log.instance(context);
+ }
+
+ public void reset()
+ {
+ deps = new HashMap<Name, Set<Name>>();
+ explicitPackages = new HashSet<Name>();
+ publicApiPerClass = new HashMap<Name,StringBuffer>();
+ }
+
+ /**
+ * Fetch the set of dependencies that are relevant to the compile
+ * that has just been performed. I.e. we are only interested in
+ * dependencies for classes that were explicitly compiled.
+ * @return
+ */
+ public Map<String,Set<String>> getDependencies() {
+ Map<String,Set<String>> new_deps = new HashMap<String,Set<String>>();
+ if (explicitPackages == null) return new_deps;
+ for (Name pkg : explicitPackages) {
+ Set<Name> set = deps.get(pkg);
+ if (set != null) {
+ Set<String> new_set = new_deps.get(pkg.toString());
+ if (new_set == null) {
+ new_set = new HashSet<String>();
+ // Modules beware....
+ new_deps.put(":"+pkg.toString(), new_set);
+ }
+ for (Name d : set) {
+ new_set.add(":"+d.toString());
+ }
+ }
+ }
+ return new_deps;
+ }
+
+ class CompareNames implements Comparator<Name> {
+ public int compare(Name a, Name b) {
+ return a.toString().compareTo(b.toString());
+ }
+
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+ }
+
+ /**
+ * Convert the map from class names to their pubapi to a map
+ * from package names to their pubapi (which is the sorted concatenation
+ * of all the class pubapis)
+ */
+ public Map<String,String> getPubapis() {
+ Map<String,String> publicApiPerPackage = new HashMap<String,String>();
+ if (publicApiPerClass == null) return publicApiPerPackage;
+ Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
+ Arrays.sort(keys, new CompareNames());
+ StringBuffer newPublicApi = new StringBuffer();
+ int i=0;
+ String prevPkg = "";
+ for (Name k : keys) {
+ String cn = k.toString();
+ String pn = "";
+ int dp = cn.lastIndexOf('.');
+ if (dp != -1) {
+ pn = cn.substring(0,dp);
+ }
+ if (!pn.equals(prevPkg)) {
+ if (!prevPkg.equals("")) {
+ // Add default module name ":"
+ publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+ }
+ newPublicApi = new StringBuffer();
+ prevPkg = pn;
+ }
+ newPublicApi.append(publicApiPerClass.get(k));
+ i++;
+ }
+ if (!prevPkg.equals(""))
+ publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+ return publicApiPerPackage;
+ }
+
+ /**
+ * Visit the api of a class and construct a pubapi string and
+ * store it into the pubapi_perclass map.
+ */
+ public void visitPubapi(Element e) {
+ Name n = ((ClassSymbol)e).fullname;
+ Name p = ((ClassSymbol)e).packge().fullname;
+ StringBuffer sb = publicApiPerClass.get(n);
+ assert(sb == null);
+ sb = new StringBuffer();
+ PubapiVisitor v = new PubapiVisitor(sb);
+ v.visit(e);
+ if (sb.length()>0) {
+ publicApiPerClass.put(n, sb);
+ }
+ explicitPackages.add(p);
+ }
+
+ /**
+ * Collect a dependency. curr_pkg is marked as depending on dep_pkg.
+ */
+ public void collect(Name currPkg, Name depPkg) {
+ if (!currPkg.equals(depPkg)) {
+ Set<Name> theset = deps.get(currPkg);
+ if (theset==null) {
+ theset = new HashSet<Name>();
+ deps.put(currPkg, theset);
+ }
+ theset.add(depPkg);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.util.StringTokenizer;
+
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.sjavac.server.CompilerThread;
+import java.io.File;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavaCompilerWithDeps extends JavaCompiler {
+
+ /** The dependency database
+ */
+ protected Dependencies deps;
+ protected CompilerThread compilerThread;
+
+ public JavaCompilerWithDeps(Context context, CompilerThread t) {
+ super(context);
+ deps = Dependencies.instance(context);
+ compilerThread = t;
+ needRootClasses = true;
+ }
+
+ public static void preRegister(Context context, final CompilerThread t) {
+ context.put(compilerKey, new Context.Factory<JavaCompiler>() {
+ public JavaCompiler make(Context c) {
+ JavaCompiler instance = new JavaCompilerWithDeps(c, t);
+ c.put(JavaCompiler.class, instance);
+ return instance;
+ }
+ });
+ }
+
+ /** Collect the public apis of classes supplied explicitly for compilation.
+ * @param sym The class to visit.
+ */
+ @Override
+ public void reportPublicApi(ClassSymbol sym) {
+ // The next test will catch when source files are located in the wrong directory!
+ // This ought to be moved into javac as a new warning, or perhaps as part
+ // of the auxiliary class warning.
+
+ // For example if sun.swing.BeanInfoUtils
+ // is in fact stored in: /mybuild/jdk/gensrc/javax/swing/beaninfo/BeanInfoUtils.java
+
+ // We do not need to test that BeanInfoUtils is stored in a file named BeanInfoUtils
+ // since this is checked earlier.
+ if (sym.sourcefile != null) {
+ // Rewrite sun.swing.BeanInfoUtils into /sun/swing/
+ StringBuilder pathb = new StringBuilder();
+ StringTokenizer qn = new StringTokenizer(sym.packge().toString(), ".");
+ boolean first = true;
+ while (qn.hasMoreTokens()) {
+ String o = qn.nextToken();
+ pathb.append("/");
+ pathb.append(o);
+ first = false;
+ }
+ pathb.append("/");
+ String path = pathb.toString();
+
+ // Now cut the uri to be: file:///mybuild/jdk/gensrc/javax/swing/beaninfo/
+ String p = sym.sourcefile.toUri().getPath();
+ // Do not use File.separatorChar here, a URI always uses slashes /.
+ int i = p.lastIndexOf("/");
+ String pp = p.substring(0,i+1);
+
+ // Now check if the truncated uri ends with the path. (It does not == failure!)
+ if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
+ compilerThread.logError("Error: The source file "+sym.sourcefile.getName()+
+ " is located in the wrong package directory, because it contains the class "+
+ sym.getQualifiedName());
+ }
+ }
+ deps.visitPubapi(sym);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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.sjavac.comp;
+
+import java.util.Iterator;
+import java.util.List;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementScanner6;
+
+/** Utility class that constructs a textual representation
+ * of the public api of a class.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class PubapiVisitor extends ElementScanner6<Void, Void> {
+
+ StringBuffer sb;
+ // Important that it is 1! Part of protocol over wire, silly yes.
+ // Fix please.
+ int indent = 1;
+
+ public PubapiVisitor(StringBuffer sb) {
+ this.sb = sb;
+ }
+
+ String depth(int l) {
+ return " ".substring(0, l);
+ }
+
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED))
+ {
+ sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n");
+ indent += 2;
+ Void v = super.visitType(e, p);
+ indent -= 2;
+ return v;
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitVariable(VariableElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED)) {
+ sb.append(depth(indent)).append("VAR ")
+ .append(makeVariableString(e)).append("\n");
+ }
+ // Safe to not recurse here, because the only thing
+ // to visit here is the constructor of a variable declaration.
+ // If it happens to contain an anonymous inner class (which it might)
+ // then this class is never visible outside of the package anyway, so
+ // we are allowed to ignore it here.
+ return null;
+ }
+
+ @Override
+ public Void visitExecutable(ExecutableElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED)) {
+ sb.append(depth(indent)).append("METHOD ")
+ .append(makeMethodString(e)).append("\n");
+ }
+ return null;
+ }
+
+ /**
+ * Creates a String representation of a method element with everything
+ * necessary to track all public aspects of it in an API.
+ * @param e Element to create String for.
+ * @return String representation of element.
+ */
+ protected String makeMethodString(ExecutableElement e) {
+ StringBuilder result = new StringBuilder();
+ for (Modifier modifier : e.getModifiers()) {
+ result.append(modifier.toString());
+ result.append(" ");
+ }
+ result.append(e.getReturnType().toString());
+ result.append(" ");
+ result.append(e.toString());
+
+ List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
+ if (!thrownTypes.isEmpty()) {
+ result.append(" throws ");
+ for (Iterator<? extends TypeMirror> iterator = thrownTypes
+ .iterator(); iterator.hasNext();) {
+ TypeMirror typeMirror = iterator.next();
+ result.append(typeMirror.toString());
+ if (iterator.hasNext()) {
+ result.append(", ");
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Creates a String representation of a variable element with everything
+ * necessary to track all public aspects of it in an API.
+ * @param e Element to create String for.
+ * @return String representation of element.
+ */
+ protected String makeVariableString(VariableElement e) {
+ StringBuilder result = new StringBuilder();
+ for (Modifier modifier : e.getModifiers()) {
+ result.append(modifier.toString());
+ result.append(" ");
+ }
+ result.append(e.asType().toString());
+ result.append(" ");
+ result.append(e.toString());
+ Object value = e.getConstantValue();
+ if (value != null) {
+ result.append(" = ");
+ if (e.asType().toString().equals("char")) {
+ int v = (int)value.toString().charAt(0);
+ result.append("'\\u"+Integer.toString(v,16)+"'");
+ } else {
+ result.append(value.toString());
+ }
+ }
+ return result.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.sjavac.comp;
+
+import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class ResolveWithDeps extends Resolve {
+
+ /** The dependency database
+ */
+ protected Dependencies deps;
+
+ protected ResolveWithDeps(Context context) {
+ super(context);
+ deps = Dependencies.instance(context);
+ }
+
+ public static void preRegister(Context context) {
+ context.put(resolveKey, new Context.Factory<Resolve>() {
+ public Resolve make(Context c) {
+ Resolve instance = new ResolveWithDeps(c);
+ c.put(Resolve.class, instance);
+ return instance;
+ }
+ });
+ }
+ /** Collect dependencies in the enclosing class
+ * @param from The enclosing class sym
+ * @param to The enclosing classes references this sym.
+ * */
+ @Override
+ public void reportDependence(Symbol from, Symbol to) {
+ // Capture dependencies between the packages.
+ deps.collect(from.packge().fullname, to.packge().fullname);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import com.sun.tools.javac.util.ListBuffer;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import javax.tools.*;
+import javax.tools.JavaFileObject.Kind;
+
+/**
+ * Intercepts reads and writes to the file system to gather
+ * information about what artifacts are generated.
+ *
+ * Traps writes to certain files, if the content written is identical
+ * to the existing file.
+ *
+ * Can also blind out the filemanager from seeing certain files in the file system.
+ * Necessary to prevent javac from seeing some sources where the source path points.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+
+ // Set of sources that can be seen by javac.
+ Set<URI> visibleSources = new HashSet<URI>();
+ // Map from modulename:packagename to artifacts.
+ Map<String,Set<URI>> packageArtifacts = new HashMap<String,Set<URI>>();
+ // Where to print informational messages.
+ PrintWriter stdout;
+
+ public SmartFileManager(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ public void setVisibleSources(Set<URI> s) {
+ visibleSources = s;
+ }
+
+ public void cleanArtifacts() {
+ packageArtifacts = new HashMap<String,Set<URI>>();
+ }
+
+ public void setLog(PrintWriter pw) {
+ stdout = pw;
+ }
+
+ public Map<String,Set<URI>> getPackageArtifacts() {
+ return packageArtifacts;
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location,
+ String packageName,
+ Set<Kind> kinds,
+ boolean recurse)
+ throws IOException
+ {
+ // Acquire the list of files.
+ Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
+ if (visibleSources.isEmpty()) {
+ return files;
+ }
+ // Now filter!
+ ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<JavaFileObject>();
+ for (JavaFileObject f : files) {
+ URI uri = f.toUri();
+ String t = uri.toString();
+ if (t.startsWith("jar:")
+ || t.endsWith(".class")
+ || visibleSources.contains(uri))
+ {
+ filteredFiles.add(f);
+ }
+ }
+ return filteredFiles;
+ }
+
+ @Override
+ public boolean hasLocation(Location location) {
+ return super.hasLocation(location);
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForInput(Location location,
+ String className,
+ Kind kind)
+ throws IOException
+ {
+ JavaFileObject file = super.getJavaFileForInput(location, className, kind);
+ if (file == null || visibleSources.isEmpty()) {
+ return file;
+ }
+
+ if (visibleSources.contains(file.toUri())) {
+ return file;
+ }
+ return null;
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(Location location,
+ String className,
+ Kind kind,
+ FileObject sibling)
+ throws IOException
+ {
+ JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
+ if (file == null) return file;
+ int dp = className.lastIndexOf('.');
+ String pkg_name = "";
+ if (dp != -1) {
+ pkg_name = className.substring(0, dp);
+ }
+ // When modules are in use, then the mod_name might be something like "jdk_base"
+ String mod_name = "";
+ addArtifact(mod_name+":"+pkg_name, file.toUri());
+ return file;
+ }
+
+ @Override
+ public FileObject getFileForInput(Location location,
+ String packageName,
+ String relativeName)
+ throws IOException
+ {
+ FileObject file = super.getFileForInput(location, packageName, relativeName);
+ if (file == null || visibleSources.isEmpty()) {
+ return file;
+ }
+
+ if (visibleSources.contains(file.toUri())) {
+ return file;
+ }
+ return null;
+ }
+
+ @Override
+ public FileObject getFileForOutput(Location location,
+ String packageName,
+ String relativeName,
+ FileObject sibling)
+ throws IOException
+ {
+ FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
+ if (file == null) return file;
+ if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
+ file instanceof JavaFileObject) {
+ file = new SmartFileObject((JavaFileObject)file, stdout);
+ packageName = ":" + packageNameFromFileName(relativeName);
+ }
+ if (packageName.equals("")) {
+ packageName = ":";
+ }
+ addArtifact(packageName, file.toUri());
+ return file;
+ }
+
+ private String packageNameFromFileName(String fn) {
+ StringBuilder sb = new StringBuilder();
+ int p = fn.indexOf('_'), pp = 0;
+ while (p != -1) {
+ if (sb.length() > 0) sb.append('.');
+ sb.append(fn.substring(pp,p));
+ if (p == fn.length()-1) break;
+ pp = p+1;
+ p = fn.indexOf('_',pp);
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ }
+
+ void addArtifact(String pkgName, URI art) {
+ Set<URI> s = packageArtifacts.get(pkgName);
+ if (s == null) {
+ s = new HashSet<URI>();
+ packageArtifacts.put(pkgName, s);
+ }
+ s.add(art);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import java.net.URI;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartFileObject will return an outputstream that cache the written data
+ * and compare the new content with the old content on disk. Only if they differ,
+ * will the file be updated.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartFileObject implements JavaFileObject {
+
+ JavaFileObject file;
+ PrintWriter stdout;
+
+ public SmartFileObject(JavaFileObject r, PrintWriter pw) {
+ file = r;
+ stdout = pw;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return file.equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ return file.hashCode();
+ }
+
+ public Kind getKind() {
+ return file.getKind();
+ }
+
+ public boolean isNameCompatible(String simpleName, Kind kind) {
+ return file.isNameCompatible(simpleName, kind);
+ }
+
+ public URI toUri() {
+ return file.toUri();
+ }
+
+ public String getName() {
+ return file.getName();
+ }
+
+ public InputStream openInputStream() throws IOException {
+ return file.openInputStream();
+ }
+
+ public OutputStream openOutputStream() throws IOException {
+ return file.openOutputStream();
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return file.getCharContent(ignoreEncodingErrors);
+ }
+
+ static String lineseparator = System.getProperty("line.separator");
+
+ public Writer openWriter() throws IOException {
+ StringBuilder s = new StringBuilder();
+ try (BufferedReader r = new BufferedReader(file.openReader(true))) {
+ while (r.ready()) {
+ s.append(r.readLine()+lineseparator);
+ }
+ } catch (FileNotFoundException e) {
+ // Perfectly ok.
+ }
+ return new SmartWriter(file, s.toString(), file.getName(), stdout);
+ }
+
+ public long getLastModified() {
+ return file.getLastModified();
+ }
+
+ public boolean delete() {
+ return file.delete();
+ }
+
+ public Modifier getAccessLevel() {
+ return file.getAccessLevel();
+ }
+
+ public NestingKind getNestingKind() {
+ return file.getNestingKind();
+ }
+
+ public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+ return file.openReader(ignoreEncodingErrors);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartWriter will cache the written data and when the writer is closed,
+ * then it will compare the cached data with the old_content string.
+ * If different, then it will write all the new content to the file.
+ * If not, the file is not touched.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartWriter extends Writer {
+
+ String name;
+ JavaFileObject file;
+ String oldContent;
+ StringWriter newContent = new StringWriter();
+ PrintWriter stdout;
+ boolean closed;
+ public SmartWriter(JavaFileObject f, String s, String n, PrintWriter pw) {
+ name = n;
+ file = f;
+ oldContent = s;
+ newContent = new StringWriter();
+ stdout = pw;
+ closed = false;
+ }
+
+ public void write(char[] chars, int i, int i1)
+ {
+ newContent.write(chars, i, i1);
+ }
+
+ public void close() throws IOException {
+ if (closed) return;
+ closed = true;
+ String s = newContent.toString();
+ if (!oldContent.equals(s)) {
+ int p = file.getName().lastIndexOf(File.separatorChar);
+ try (Writer writer = file.openWriter()) {
+ writer.write(s);
+ }
+ stdout.println("Writing "+file.getName().substring(p+1));
+ }
+ }
+
+ public void flush() throws IOException {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerPool.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.Stack;
+import java.util.concurrent.Future;
+
+/** The compiler pool maintains compiler threads.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompilerPool {
+ // The javac server that created this pool.
+ private JavacServer javacServer;
+ // A semaphore protecting the poolsize number of threads.
+ private Semaphore available;
+ // The stack of compiler threads.
+ private Stack<CompilerThread> compilers = new Stack<CompilerThread>();
+ // And the executor server to spawn threads.
+ private final ExecutorService executorPool;
+ // How many requests are active right now?
+ private int concurrentRequests = 0;
+ // When was the last request finished?
+ private long lastRequestFinished = 0;
+ // The total number of requests to this pool.
+ private int numRequests = 0;
+ // Protect access to the three above values.
+ private static final Object conc = new Object();
+
+ /**
+ * Return the javac server that this pool belongs to.
+ */
+ public JavacServer getJavacServer() {
+ return javacServer;
+ }
+
+ /**
+ * Return how many threads are running at this very moment.
+ */
+ public int numActiveRequests()
+ {
+ synchronized (conc) {
+ return concurrentRequests;
+ }
+ }
+
+ /**
+ * Return when the last request was finished.
+ * I.e. the pool has been idle since.
+ */
+ public long lastRequestFinished()
+ {
+ synchronized (conc) {
+ return lastRequestFinished;
+ }
+ }
+
+ /**
+ * Up the number of active requests.
+ */
+ public int startRequest() {
+ int n;
+ synchronized (conc) {
+ concurrentRequests++;
+ numRequests++;
+ n = numRequests;
+ }
+ return n;
+ }
+
+ /**
+ * Down the number of active requests. Return the current time.
+ */
+ public long stopRequest() {
+ synchronized (conc) {
+ concurrentRequests--;
+ lastRequestFinished = System.currentTimeMillis();
+ }
+ return lastRequestFinished;
+ }
+
+ /**
+ * Create a new compiler pool.
+ */
+ CompilerPool(int poolsize, JavacServer server) {
+ available = new Semaphore(poolsize, true);
+ javacServer = server;
+ executorPool = Executors.newFixedThreadPool(poolsize);
+ lastRequestFinished = System.currentTimeMillis();
+ }
+
+ /**
+ * Execute a compiler thread.
+ */
+ public void execute(CompilerThread ct) {
+ executorPool.execute(ct);
+ }
+
+ /**
+ * Execute a minor task, for example generating bytecodes and writing them to disk,
+ * that belong to a major compiler thread task.
+ */
+ public Future<?> executeSubtask(CompilerThread t, Runnable r) {
+ return executorPool.submit(r);
+ }
+
+ /**
+ * Shutdown the pool.
+ */
+ public void shutdown() {
+ executorPool.shutdown();
+ }
+
+ /**
+ * Acquire a compiler thread from the pool, or block until a thread is available.
+ * If the pools is empty, create a new thread, but never more than is "available".
+ */
+ public CompilerThread grabCompilerThread() throws InterruptedException {
+ available.acquire();
+ if (compilers.empty()) {
+ return new CompilerThread(this);
+ }
+ return compilers.pop();
+ }
+
+ /**
+ * Return the specified compiler thread to the pool.
+ */
+ public void returnCompilerThread(CompilerThread h) {
+ compilers.push(h);
+ available.release();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.concurrent.Future;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.BaseFileManager;
+import com.sun.tools.sjavac.comp.Dependencies;
+import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
+import com.sun.tools.sjavac.comp.SmartFileManager;
+import com.sun.tools.sjavac.comp.ResolveWithDeps;
+
+/**
+ * The compiler thread maintains a JavaCompiler instance and
+ * can receive a request from the client, perform the compilation
+ * requested and report back the results.
+ *
+ * * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompilerThread implements Runnable {
+ private JavacServer javacServer;
+ private CompilerPool compilerPool;
+ private List<Future<?>> subTasks;
+
+ // Communicating over this socket.
+ private Socket socket;
+
+ // The necessary classes to do a compilation.
+ private com.sun.tools.javac.api.JavacTool compiler;
+ private StandardJavaFileManager fileManager;
+ private BaseFileManager fileManagerBase;
+ private SmartFileManager smartFileManager;
+ private Context context;
+
+ // If true, then this thread is serving a request.
+ private boolean inUse = false;
+
+ CompilerThread(CompilerPool cp) {
+ compilerPool = cp;
+ javacServer = cp.getJavacServer();
+ }
+
+ /**
+ * Execute a minor task, for example generating bytecodes and writing them to disk,
+ * that belong to a major compiler thread task.
+ */
+ public synchronized void executeSubtask(Runnable r) {
+ subTasks.add(compilerPool.executeSubtask(this, r));
+ }
+
+ /**
+ * Count the number of active sub tasks.
+ */
+ public synchronized int numActiveSubTasks() {
+ int c = 0;
+ for (Future<?> f : subTasks) {
+ if (!f.isDone() && !f.isCancelled()) {
+ c++;
+ }
+ }
+ return c;
+ }
+
+ /**
+ * Use this socket for the upcoming request.
+ */
+ public void setSocket(Socket s) {
+ socket = s;
+ }
+
+ /**
+ * Prepare the compiler thread for use. It is not yet started.
+ * It will be started by the executor service.
+ */
+ public synchronized void use() {
+ assert(!inUse);
+ inUse = true;
+ compiler = com.sun.tools.javac.api.JavacTool.create();
+ fileManager = compiler.getStandardFileManager(null, null, null);
+ fileManagerBase = (BaseFileManager)fileManager;
+ smartFileManager = new SmartFileManager(fileManager);
+ context = new Context();
+ context.put(JavaFileManager.class, smartFileManager);
+ ResolveWithDeps.preRegister(context);
+ JavaCompilerWithDeps.preRegister(context, this);
+ subTasks = new ArrayList<Future<?>>();
+ }
+
+ /**
+ * Prepare the compiler thread for idleness.
+ */
+ public synchronized void unuse() {
+ assert(inUse);
+ inUse = false;
+ compiler = null;
+ fileManager = null;
+ fileManagerBase = null;
+ smartFileManager = null;
+ context = null;
+ subTasks = null;
+ }
+
+ /**
+ * Expect this key on the next line read from the reader.
+ */
+ private static boolean expect(BufferedReader in, String key) throws IOException {
+ String s = in.readLine();
+ if (s != null && s.equals(key)) {
+ return true;
+ }
+ return false;
+ }
+
+ // The request identifier, for example GENERATE_NEWBYTECODE
+ String id = "";
+
+ public String currentRequestId() {
+ return id;
+ }
+
+ PrintWriter stdout;
+ PrintWriter stderr;
+ int forcedExitCode = 0;
+
+ public void logError(String msg) {
+ stderr.println(msg);
+ forcedExitCode = -1;
+ }
+
+ /**
+ * Invoked by the executor service.
+ */
+ public void run() {
+ // Unique nr that identifies this request.
+ int thisRequest = compilerPool.startRequest();
+ long start = System.currentTimeMillis();
+ int numClasses = 0;
+ StringBuilder compiledPkgs = new StringBuilder();
+ use();
+
+ PrintWriter out = null;
+ try {
+ javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ socket.getInputStream()));
+ out = new PrintWriter(new OutputStreamWriter(
+ socket.getOutputStream()));
+ if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
+ javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
+ return;
+ }
+
+ String cookie = in.readLine();
+ if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
+ javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
+ return;
+ }
+ if (!expect(in, JavacServer.PROTOCOL_CWD)) {
+ return;
+ }
+ String cwd = in.readLine();
+ if (cwd == null)
+ return;
+ if (!expect(in, JavacServer.PROTOCOL_ID)) {
+ return;
+ }
+ id = in.readLine();
+ if (id == null)
+ return;
+ if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
+ return;
+ }
+ ArrayList<String> the_options = new ArrayList<String>();
+ ArrayList<File> the_classes = new ArrayList<File>();
+ Iterable<File> path = Arrays.<File> asList(new File(cwd));
+
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
+ break;
+ if (l.startsWith("--server:"))
+ continue;
+ if (!l.startsWith("-") && l.endsWith(".java")) {
+ the_classes.add(new File(l));
+ numClasses++;
+ } else {
+ the_options.add(l);
+ }
+ continue;
+ }
+
+ // Load sources to compile
+ Set<URI> sourcesToCompile = new HashSet<URI>();
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
+ break;
+ try {
+ sourcesToCompile.add(new URI(l));
+ numClasses++;
+ } catch (URISyntaxException e) {
+ return;
+ }
+ }
+ // Load visible sources
+ Set<URI> visibleSources = new HashSet<URI>();
+ boolean fix_drive_letter_case = System.getProperty("os.name").toLowerCase().equals("windows");
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_END))
+ break;
+ try {
+ URI u = new URI(l);
+ if (fix_drive_letter_case) {
+ // Make sure the driver letter is lower case.
+ String s = u.toString();
+ if (s.startsWith("file:/") &&
+ Character.isUpperCase(s.charAt(6))) {
+ u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
+ }
+ }
+ visibleSources.add(u);
+ } catch (URISyntaxException e) {
+ return;
+ }
+ }
+
+ // A completed request has been received.
+
+ // Now setup the actual compilation....
+ // First deal with explicit source files on cmdline and in at file.
+ com.sun.tools.javac.util.ListBuffer<JavaFileObject> compilationUnits =
+ new com.sun.tools.javac.util.ListBuffer<JavaFileObject>();
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
+ compilationUnits.append(i);
+ }
+ // Now deal with sources supplied as source_to_compile.
+ com.sun.tools.javac.util.ListBuffer<File> sourcesToCompileFiles =
+ new com.sun.tools.javac.util.ListBuffer<File>();
+ for (URI u : sourcesToCompile) {
+ sourcesToCompileFiles.append(new File(u));
+ }
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
+ compilationUnits.append(i);
+ }
+ // Log the options to be used.
+ StringBuilder options = new StringBuilder();
+ for (String s : the_options) {
+ options.append(">").append(s).append("< ");
+ }
+ javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
+
+ forcedExitCode = 0;
+ // Create a new logger.
+ StringWriter stdoutLog = new StringWriter();
+ StringWriter stderrLog = new StringWriter();
+ stdout = new PrintWriter(stdoutLog);
+ stderr = new PrintWriter(stderrLog);
+ com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+ try {
+ if (compilationUnits.size() > 0) {
+ // Bind the new logger to the existing context.
+ context.put(Log.outKey, stderr);
+ Log.instance(context).setWriter(Log.WriterKind.NOTICE, stdout);
+ Log.instance(context).setWriter(Log.WriterKind.WARNING, stderr);
+ Log.instance(context).setWriter(Log.WriterKind.ERROR, stderr);
+ // Process the options.
+ com.sun.tools.javac.api.JavacTool.processOptions(context, smartFileManager, the_options);
+ fileManagerBase.setContext(context);
+ smartFileManager.setVisibleSources(visibleSources);
+ smartFileManager.cleanArtifacts();
+ smartFileManager.setLog(stdout);
+ Dependencies.instance(context).reset();
+
+ com.sun.tools.javac.main.Main ccompiler = new com.sun.tools.javac.main.Main("javacTask", stderr);
+ String[] aa = the_options.toArray(new String[0]);
+
+ // Do the compilation!
+ rc = ccompiler.compile(aa, context, compilationUnits.toList(), null);
+
+ while (numActiveSubTasks()>0) {
+ try { Thread.sleep(1000); } catch (InterruptedException e) { }
+ }
+
+ smartFileManager.flush();
+ }
+ } catch (Exception e) {
+ stderr.println(e.getMessage());
+ forcedExitCode = -1;
+ }
+
+ // Send the response..
+ out.println(JavacServer.PROTOCOL_STDOUT);
+ out.print(stdoutLog);
+ out.println(JavacServer.PROTOCOL_STDERR);
+ out.print(stderrLog);
+ // The compilation is complete! And errors will have already been printed on out!
+ out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
+ Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
+ for (String aPkgName : pa.keySet()) {
+ out.println("+"+aPkgName);
+ Set<URI> as = pa.get(aPkgName);
+ for (URI a : as) {
+ out.println(" "+a.toString());
+ }
+ }
+ Dependencies deps = Dependencies.instance(context);
+ out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
+ Map<String,Set<String>> pd = deps.getDependencies();
+ for (String aPkgName : pd.keySet()) {
+ out.println("+"+aPkgName);
+ Set<String> ds = pd.get(aPkgName);
+ // Everything depends on java.lang
+ if (!ds.contains(":java.lang")) ds.add(":java.lang");
+ for (String d : ds) {
+ out.println(" "+d);
+ }
+ }
+ out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
+ Map<String,String> pp = deps.getPubapis();
+ for (String aPkgName : pp.keySet()) {
+ out.println("+"+aPkgName);
+ String ps = pp.get(aPkgName);
+ // getPubapis added a space to each line!
+ out.println(ps);
+ compiledPkgs.append(aPkgName+" ");
+ }
+ out.println(JavacServer.PROTOCOL_SYSINFO);
+ out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
+ out.println("max_memory=" + Runtime.getRuntime().maxMemory());
+ out.println(JavacServer.PROTOCOL_RETURN_CODE);
+
+ // Errors from sjavac that affect compilation status!
+ int rcv = rc.exitCode;
+ if (rcv == 0 && forcedExitCode != 0) {
+ rcv = forcedExitCode;
+ }
+ out.println("" + rcv);
+ out.println(JavacServer.PROTOCOL_END);
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (out != null) out.close();
+ if (!socket.isClosed()) {
+ socket.close();
+ }
+ socket = null;
+ } catch (Exception e) {
+ javacServer.log("ERROR "+e);
+ e.printStackTrace();
+ }
+ compilerPool.stopRequest();
+ long duration = System.currentTimeMillis()-start;
+ javacServer.addBuildTime(duration);
+ float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
+ javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms num_classes="+numClasses+
+ " classpersec="+classpersec+" subtasks="+subTasks.size());
+ javacServer.flushLog();
+ unuse();
+ compilerPool.returnCompilerThread(this);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Random;
+
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.ProblemException;
+import java.io.*;
+import java.util.*;
+
+/**
+ * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are
+ * subject to change or deletion without notice.</b></p>
+ */
+public class JavacServer {
+ // Responding to this tcp/ip port on localhost.
+
+ private final ServerSocket serverSocket;
+ // The secret cookie shared between server and client through the port file.
+ private final long myCookie;
+ // When the server was started.
+ private long serverStart;
+ // Accumulated build time for all requests, not counting idle time.
+ private long totalBuildTime;
+ // The javac server specific log file.
+ PrintWriter theLog;
+ // The compiler pool that maintains the compiler threads.
+ CompilerPool compilerPool;
+ // For the client, all port files fetched, one per started javac server.
+ // Though usually only one javac server is started by a client.
+ private static Map<String, PortFile> allPortFiles;
+ private static Map<String, Long> maxServerMemory;
+ final static int ERROR_FATAL = -1;
+ final static int ERROR_BUT_TRY_AGAIN = -4712;
+ final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
+ final static String PROTOCOL_CWD = "----THE-CWD----";
+ final static String PROTOCOL_ID = "----THE-ID----";
+ final static String PROTOCOL_ARGS = "----THE-ARGS----";
+ final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
+ final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
+ final static String PROTOCOL_END = "----THE-END----";
+ final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
+ final static String PROTOCOL_STDERR = "----THE-STDERR----";
+ final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
+ final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
+ final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
+ final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
+ final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
+ // Check if the portfile is gone, every 5 seconds.
+ static int CHECK_PORTFILE_INTERVAL = 5;
+ // Wait 2 seconds for response, before giving up on javac server.
+ static int CONNECTION_TIMEOUT = 2;
+ static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
+ static int MAX_NUM_CONNECT_ATTEMPTS = 3;
+
+ /**
+ * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
+ */
+ private static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
+ if (allPortFiles == null) {
+ allPortFiles = new HashMap<String, PortFile>();
+ }
+ PortFile pf = allPortFiles.get(filename);
+ if (pf == null) {
+ pf = new PortFile(filename);
+ allPortFiles.put(filename, pf);
+ }
+ return pf;
+ }
+
+ /**
+ * Get the cookie used for this server.
+ */
+ long getCookie() {
+ return myCookie;
+ }
+
+ /**
+ * Get the port used for this server.
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Sum up the total build time for this javac server.
+ */
+ public void addBuildTime(long inc) {
+ totalBuildTime += inc;
+ }
+
+ /**
+ * Log this message.
+ */
+ public void log(String msg) {
+ if (theLog != null) {
+ theLog.println(msg);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ /**
+ * Make sure the log is flushed.
+ */
+ public void flushLog() {
+ if (theLog != null) {
+ theLog.flush();
+ }
+ }
+
+ /**
+ * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
+ * is sent as the settings parameter. Returns 0 on success, -1 on failure.
+ */
+ public static int startServer(String settings, PrintStream err) {
+ try {
+ String portfile = Util.extractStringOption("portfile", settings);
+ // The log file collects more javac server specific log information.
+ String logfile = Util.extractStringOption("logfile", settings);
+ // The stdouterr file collects all the System.out and System.err writes to disk.
+ String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+ // We could perhaps use System.setOut and setErr here.
+ // But for the moment we rely on the client to spawn a shell where stdout
+ // and stderr are redirected already.
+ // The pool size is a limit the number of concurrent compiler threads used.
+ // The server might use less than these to avoid memory problems.
+ int poolsize = Util.extractIntOption("poolsize", settings);
+ if (poolsize <= 0) {
+ // If not set, default to the number of cores.
+ poolsize = Runtime.getRuntime().availableProcessors();
+ }
+
+ // How many seconds of inactivity will the server accept before quitting?
+ int keepalive = Util.extractIntOption("keepalive", settings);
+ if (keepalive <= 0) {
+ keepalive = 120;
+ }
+ // The port file is locked and the server port and cookie is written into it.
+ PortFile portFile = getPortFile(portfile);
+ JavacServer s;
+
+ synchronized (portFile) {
+ portFile.lock();
+ portFile.getValues();
+ if (portFile.containsPortInfo()) {
+ err.println("Javac server not started because portfile exists!");
+ portFile.unlock();
+ return -1;
+ }
+ s = new JavacServer(poolsize, logfile);
+ portFile.setValues(s.getPort(), s.getCookie());
+ portFile.unlock();
+ }
+
+ // Run the server. Will delete the port file when shutting down.
+ // It will shut down automatically when no new requests have come in
+ // during the last 125 seconds.
+ s.run(portFile, err, keepalive);
+ // The run loop for the server has exited.
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ /**
+ * Dispatch a compilation request to a javac server.
+ *
+ * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
+ *
+ * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
+ *
+ * @param sources_to_compile The sources to compile.
+ *
+ * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
+ * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
+ *
+ * @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
+ * can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
+ *
+ * The server return meta data about the build in the following parameters.
+ * @param package_artifacts, map from package name to set of created artifacts for that package.
+ * @param package_dependencies, map from package name to set of packages that it depends upon.
+ * @param package_pubapis, map from package name to unique string identifying its pub api.
+ */
+ public static int useServer(String settings, String[] args,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources,
+ Map<URI, Set<String>> visibleClasses,
+ Map<String, Set<URI>> packageArtifacts,
+ Map<String, Set<String>> packageDependencies,
+ Map<String, String> packagePubapis,
+ SysInfo sysinfo,
+ PrintStream out,
+ PrintStream err) {
+ try {
+ // The id can perhaps be used in the future by the javac server to reuse the
+ // JavaCompiler instance for several compiles using the same id.
+ String id = Util.extractStringOption("id", settings);
+ String portfile = Util.extractStringOption("portfile", settings);
+ String logfile = Util.extractStringOption("logfile", settings);
+ String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+ String background = Util.extractStringOption("background", settings);
+ if (background == null || !background.equals("false")) {
+ background = "true";
+ }
+ // The sjavac option specifies how the server part of sjavac is spawned.
+ // If you have the experimental sjavac in your path, you are done. If not, you have
+ // to point to a com.sun.tools.sjavac.Main that supports --startserver
+ // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
+ String sjavac = Util.extractStringOption("sjavac", settings);
+ int poolsize = Util.extractIntOption("poolsize", settings);
+ int keepalive = Util.extractIntOption("keepalive", settings);
+
+ if (keepalive <= 0) {
+ // Default keepalive for server is 120 seconds.
+ // I.e. it will accept 120 seconds of inactivity before quitting.
+ keepalive = 120;
+ }
+ if (portfile == null) {
+ err.println("No portfile was specified!");
+ return -1;
+ }
+ if (logfile == null) {
+ logfile = portfile + ".javaclog";
+ }
+ if (stdouterrfile == null) {
+ stdouterrfile = portfile + ".stdouterr";
+ }
+ // Default to sjavac and hope it is in the path.
+ if (sjavac == null) {
+ sjavac = "sjavac";
+ }
+
+ int attempts = 0;
+ int rc = -1;
+ do {
+ PortFile port_file = getPortFile(portfile);
+ synchronized (port_file) {
+ port_file.lock();
+ port_file.getValues();
+ port_file.unlock();
+ }
+ if (!port_file.containsPortInfo()) {
+ String cmd = fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, err, stdouterrfile, background);
+
+ if (background.equals("true") && !port_file.waitForValidValues()) {
+ // Ouch the server did not start! Lets print its stdouterrfile and the command used.
+ printFailedAttempt(cmd, stdouterrfile, err);
+ // And give up.
+ return -1;
+ }
+ }
+ rc = connectAndCompile(port_file, id, args, sourcesToCompile, visibleSources,
+ packageArtifacts, packageDependencies, packagePubapis, sysinfo,
+ out, err);
+ // Try again until we manage to connect. Any error after that
+ // will cause the compilation to fail.
+ if (rc == ERROR_BUT_TRY_AGAIN) {
+ // We could not connect to the server. Try again.
+ attempts++;
+ try {
+ Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+ } catch (InterruptedException e) {
+ }
+ }
+ } while (rc == ERROR_BUT_TRY_AGAIN && attempts < MAX_NUM_CONNECT_ATTEMPTS);
+ return rc;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ private static void printFailedAttempt(String cmd, String f, PrintStream err) {
+ err.println("---- Failed to start javac server with this command -----");
+ err.println(cmd);
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(f));
+ err.println("---- stdout/stderr output from attempt to start javac server -----");
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ break;
+ }
+ err.println(l);
+ }
+ err.println("------------------------------------------------------------------");
+ } catch (Exception e) {
+ err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
+ }
+ }
+
+ /**
+ * Spawn the server instance.
+ */
+
+ private JavacServer(int poolSize, String logfile) throws IOException {
+ serverStart = System.currentTimeMillis();
+ // Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
+ // I.e only local processes can connect to this port.
+ serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
+ compilerPool = new CompilerPool(poolSize, this);
+ Random rnd = new Random();
+ myCookie = rnd.nextLong();
+ theLog = new PrintWriter(logfile);
+ log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
+ flushLog();
+ }
+
+ /**
+ * Fork a background process. Returns the command line used that can be printed if something failed.
+ */
+ private static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
+ final PrintStream err, String stdouterrfile, String background)
+ throws IOException, ProblemException {
+ if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
+ stdouterrfile = null;
+ }
+ final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
+
+ if (background.equals("true")) {
+ sjavac += "%20" + startserver;
+ sjavac = sjavac.replaceAll("%20", " ");
+ sjavac = sjavac.replaceAll("%2C", ",");
+ // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
+ String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
+ if (!(new File("/bin/sh")).canExecute()) {
+ ArrayList<String> wincmd = new ArrayList<String>();
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add("start");
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
+ cmd = wincmd.toArray(new String[wincmd.size()]);
+ }
+ Process pp = null;
+ try {
+ pp = Runtime.getRuntime().exec(cmd);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ e.printStackTrace(new PrintWriter(stdouterrfile));
+ }
+ StringBuilder rs = new StringBuilder();
+ for (String s : cmd) {
+ rs.append(s + " ");
+ }
+ return rs.toString();
+ }
+
+ // Do not spawn a background server, instead run it within the same JVM.
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ JavacServer.startServer(startserver, err);
+ } catch (Throwable t) {
+ t.printStackTrace(err);
+ }
+ }
+ };
+ t.start();
+ return "";
+ }
+
+ /**
+ * Expect this key on the next line read from the reader.
+ */
+ private static boolean expect(BufferedReader in, String key) throws IOException {
+ String s = in.readLine();
+ if (s != null && s.equals(key)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Make a request to the server only to get the maximum possible heap size to use for compilations.
+ *
+ * @param port_file The port file used to synchronize creation of this server.
+ * @param id The identify of the compilation.
+ * @param out Standard out information.
+ * @param err Standard err information.
+ * @return The maximum heap size in bytes.
+ */
+ public static SysInfo connectGetSysInfo(String serverSettings, PrintStream out, PrintStream err) {
+ SysInfo sysinfo = new SysInfo(-1, -1);
+ String id = Util.extractStringOption("id", serverSettings);
+ String portfile = Util.extractStringOption("portfile", serverSettings);
+ try {
+ PortFile pf = getPortFile(portfile);
+ useServer(serverSettings, new String[0],
+ new HashSet<URI>(),
+ new HashSet<URI>(),
+ new HashMap<URI, Set<String>>(),
+ new HashMap<String, Set<URI>>(),
+ new HashMap<String, Set<String>>(),
+ new HashMap<String, String>(),
+ sysinfo, out, err);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ }
+ return sysinfo;
+ }
+
+ /**
+ * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
+ * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
+ */
+ private static int connectAndCompile(PortFile portFile, String id, String[] args,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources,
+ Map<String, Set<URI>> packageArtifacts,
+ Map<String, Set<String>> packageDependencies,
+ Map<String, String> packagePublicApis,
+ SysInfo sysinfo,
+ PrintStream out,
+ PrintStream err) {
+ int rc = -3;
+ try {
+ int port = portFile.getPort();
+ if (port == 0) {
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ long cookie = portFile.getCookie();
+
+ // Acquire the localhost/127.0.0.1 address.
+ InetAddress addr = InetAddress.getByName(null);
+ SocketAddress sockaddr = new InetSocketAddress(addr, port);
+ Socket sock = new Socket();
+ int timeoutMs = CONNECTION_TIMEOUT * 1000;
+ try {
+ sock.connect(sockaddr, timeoutMs);
+ } catch (java.net.ConnectException e) {
+ err.println("Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e);
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ if (!sock.isConnected()) {
+ err.println("Could not connect to javac server found in portfile: " + portFile.getFilename());
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ PrintWriter sockout = new PrintWriter(sock.getOutputStream());
+
+ sockout.println(PROTOCOL_COOKIE_VERSION);
+ sockout.println("" + cookie);
+ sockout.println(PROTOCOL_CWD);
+ sockout.println(System.getProperty("user.dir"));
+ sockout.println(PROTOCOL_ID);
+ sockout.println(id);
+ sockout.println(PROTOCOL_ARGS);
+ for (String s : args) {
+ StringBuffer buf = new StringBuffer();
+ String[] paths = s.split(File.pathSeparator);
+ int c = 0;
+ for (String path : paths) {
+ File f = new File(path);
+ if (f.isFile() || f.isDirectory()) {
+ buf.append(f.getAbsolutePath());
+ c++;
+ if (c < paths.length) {
+ buf.append(File.pathSeparator);
+ }
+ } else {
+ buf = new StringBuffer(s);
+ break;
+ }
+ }
+ sockout.println(buf.toString());
+ }
+ sockout.println(PROTOCOL_SOURCES_TO_COMPILE);
+ for (URI uri : sourcesToCompile) {
+ sockout.println(uri.toString());
+ }
+ sockout.println(PROTOCOL_VISIBLE_SOURCES);
+ for (URI uri : visibleSources) {
+ sockout.println(uri.toString());
+ }
+ sockout.println(PROTOCOL_END);
+ sockout.flush();
+
+ StringBuffer stdout = new StringBuffer();
+ StringBuffer stderr = new StringBuffer();
+
+ if (!expect(in, PROTOCOL_STDOUT)) {
+ return ERROR_FATAL;
+ }
+ // Load stdout
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_STDERR)) {
+ break;
+ }
+ stdout.append(l);
+ stdout.append('\n');
+ }
+ // Load stderr
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_ARTIFACTS)) {
+ break;
+ }
+ stderr.append(l);
+ stderr.append('\n');
+ }
+ // Load the package artifacts
+ Set<URI> lastUriSet = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_DEPENDENCIES)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastUriSet = new HashSet<URI>();
+ packageArtifacts.put(pkg, lastUriSet);
+ } else if (l.length() > 1 && lastUriSet != null) {
+ lastUriSet.add(new URI(l.substring(1)));
+ }
+ }
+ // Load package dependencies
+ Set<String> lastPackageSet = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_PUBLIC_APIS)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastPackageSet = new HashSet<String>();
+ packageDependencies.put(pkg, lastPackageSet);
+ } else if (l.length() > 1 && lastPackageSet != null) {
+ lastPackageSet.add(l.substring(1));
+ }
+ }
+ // Load package pubapis
+ Map<String, StringBuffer> tmp = new HashMap<String, StringBuffer>();
+ StringBuffer lastPublicApi = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_SYSINFO)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastPublicApi = new StringBuffer();
+ tmp.put(pkg, lastPublicApi);
+ } else if (l.length() > 1 && lastPublicApi != null) {
+ lastPublicApi.append(l.substring(1));
+ lastPublicApi.append("\n");
+ }
+ }
+ for (String p : tmp.keySet()) {
+ assert (packagePublicApis.get(p) == null);
+ String api = tmp.get(p).toString();
+ packagePublicApis.put(p, api);
+ }
+ // Now reading the max memory possible.
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_RETURN_CODE)) {
+ break;
+ }
+ if (l.startsWith("num_cores=") && sysinfo != null) {
+ sysinfo.numCores = Integer.parseInt(l.substring(10));
+ }
+ if (l.startsWith("max_memory=") && sysinfo != null) {
+ sysinfo.maxMemory = Long.parseLong(l.substring(11));
+ }
+ }
+ String l = in.readLine();
+ if (l == null) {
+ err.println("No return value from the server!");
+ return ERROR_FATAL;
+ }
+ rc = Integer.parseInt(l);
+ out.print(stdout);
+ err.print(stderr);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ }
+ return rc;
+ }
+
+ /**
+ * Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
+ * javac server.
+ */
+ private void run(PortFile portFile, PrintStream err, int keepalive) {
+ boolean fileDeleted = false;
+ long timeSinceLastCompile;
+ try {
+ // Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
+ // Or if the last request was finished more than 125 seconds ago => quit
+ // 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
+ serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
+ for (;;) {
+ try {
+ Socket s = serverSocket.accept();
+ CompilerThread ct = compilerPool.grabCompilerThread();
+ ct.setSocket(s);
+ compilerPool.execute(ct);
+ flushLog();
+ } catch (java.net.SocketTimeoutException e) {
+ if (compilerPool.numActiveRequests() > 0) {
+ // Never quit while there are active requests!
+ continue;
+ }
+ // If this is the timeout after the portfile
+ // has been deleted by us. Then we truly stop.
+ if (fileDeleted) {
+ log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
+ break;
+ }
+ // Check if the portfile is still there.
+ if (!portFile.exists()) {
+ // Time to quit because the portfile was deleted by another
+ // process, probably by the makefile that is done building.
+ log("Quitting because portfile was deleted!");
+ flushLog();
+ break;
+ }
+ // Check if portfile.stop is still there.
+ if (portFile.markedForStop()) {
+ // Time to quit because another process touched the file
+ // server.port.stop to signal that the server should stop.
+ // This is necessary on some operating systems that lock
+ // the port file hard!
+ log("Quitting because a portfile.stop file was found!");
+ portFile.delete();
+ flushLog();
+ break;
+ }
+ // Does the portfile still point to me?
+ if (!portFile.stillMyValues()) {
+ // Time to quit because another build has started.
+ log("Quitting because portfile is now owned by another javac server!");
+ flushLog();
+ break;
+ }
+
+ // Check how long since the last request finished.
+ long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
+ if (diff < keepalive * 1000) {
+ // Do not quit if we have waited less than 120 seconds.
+ continue;
+ }
+ // Ok, time to quit because of inactivity. Perhaps the build
+ // was killed and the portfile not cleaned up properly.
+ portFile.delete();
+ fileDeleted = true;
+ log("" + keepalive + " seconds of inactivity quitting in "
+ + CHECK_PORTFILE_INTERVAL + " seconds!");
+ flushLog();
+ // Now we have a second 5 second grace
+ // period where javac remote requests
+ // that have loaded the data from the
+ // recently deleted portfile can connect
+ // and complete their requests.
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ e.printStackTrace(theLog);
+ flushLog();
+ } finally {
+ compilerPool.shutdown();
+ }
+ long realTime = System.currentTimeMillis() - serverStart;
+ log("Shutting down.");
+ log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
+ flushLog();
+ }
+
+ public static void cleanup(String... args) {
+ String settings = Util.findServerSettings(args);
+ if (settings == null) return;
+ String portfile = Util.extractStringOption("portfile", settings);
+ String background = Util.extractStringOption("background", settings);
+ if (background != null && background.equals("false")) {
+ // If the server runs within this jvm, then delete the portfile,
+ // since this jvm is about to exit soon.
+ File f = new File(portfile);
+ f.delete();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.FileLockInterruptionException;
+import com.sun.tools.sjavac.Log;
+
+/**
+ * The PortFile class mediates access to a short binary file containing the tcp/ip port (for the localhost)
+ * and a cookie necessary for the server answering on that port. The file can be locked using file system
+ * primitives to avoid race conditions when several javac clients are started at the same. Note that file
+ * system locking is not always supported on a all operating systems and/or file systems.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+class PortFile {
+
+ // Port file format:
+ // byte ordering: high byte first = big endian
+ // Magic nr, 4 byte int, first in file.
+ private final static int magicNr = 0x1174;
+ // Followed by a 4 byte int, with the port nr.
+ // Followed by a 8 byte long, with cookie nr.
+
+ private String filename;
+ private File file;
+ private File stopFile;
+ private RandomAccessFile rwfile;
+ private FileChannel channel;
+ private FileLock lock;
+
+ private boolean containsPortInfo;
+ private int serverPort;
+ private long serverCookie;
+ private int myServerPort;
+ private long myServerCookie;
+
+ /**
+ * Create a new portfile.
+ * @param filename is the path to the file.
+ */
+ public PortFile(String fn) throws FileNotFoundException
+ {
+ filename = fn;
+ file = new File(filename);
+ stopFile = new File(filename+".stop");
+ rwfile = new RandomAccessFile(file, "rw");
+ // The rwfile should only be readable by the owner of the process
+ // and no other! How do we do that on a RandomAccessFile?
+ channel = rwfile.getChannel();
+ containsPortInfo = false;
+ lock = null;
+ }
+
+ /**
+ * Lock the port file.
+ */
+ void lock() throws IOException {
+ lock = channel.lock();
+ }
+
+ /**
+ * Read the values from the port file in the file system.
+ * Expects the port file to be locked.
+ */
+ public void getValues() {
+ containsPortInfo = false;
+ if (lock == null) {
+ // Not locked, remain ignorant about port file contents.
+ return;
+ }
+ try {
+ if (rwfile.length()>0) {
+ rwfile.seek(0);
+ int nr = rwfile.readInt();
+ serverPort = rwfile.readInt();
+ serverCookie = rwfile.readLong();
+
+ if (nr == magicNr) {
+ containsPortInfo = true;
+ } else {
+ containsPortInfo = false;
+ }
+ }
+ } catch (Exception e) {
+ containsPortInfo = false;
+ }
+ }
+
+ /**
+ * Did the locking and getValues succeed?
+ */
+ public boolean containsPortInfo() {
+ return containsPortInfo;
+ }
+
+ /**
+ * If so, then we can acquire the tcp/ip port on localhost.
+ */
+ public int getPort() {
+ assert(containsPortInfo);
+ return serverPort;
+ }
+
+ /**
+ * If so, then we can acquire the server cookie.
+ */
+ public long getCookie() {
+ assert(containsPortInfo);
+ return serverCookie;
+ }
+
+ /**
+ * Store the values into the locked port file.
+ */
+ public void setValues(int port, long cookie) throws IOException {
+ assert(lock != null);
+ rwfile.seek(0);
+ // Write the magic nr that identifes a port file.
+ rwfile.writeInt(magicNr);
+ rwfile.writeInt(port);
+ rwfile.writeLong(cookie);
+ myServerPort = port;
+ myServerCookie = cookie;
+ }
+
+ /**
+ * Delete the port file.
+ */
+ public void delete() throws IOException {
+ // Access to file must be closed before deleting.
+ rwfile.close();
+ // Now delete.
+ file.delete();
+ }
+
+ /**
+ * Is the port file still there?
+ */
+ public boolean exists() throws IOException {
+ return file.exists();
+ }
+
+ /**
+ * Is a stop file there?
+ */
+ public boolean markedForStop() throws IOException {
+ if (stopFile.exists()) {
+ try {
+ stopFile.delete();
+ } catch (Exception e)
+ {}
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Unlock the port file.
+ */
+ public void unlock() throws IOException {
+ assert(lock != null);
+ lock.release();
+ lock = null;
+ }
+
+ /**
+ * Wait for the port file to contain values that look valid.
+ * Return true, if a-ok, false if the valid values did not materialize within 5 seconds.
+ */
+ public synchronized boolean waitForValidValues() throws IOException, FileNotFoundException {
+ for (int tries = 0; tries < 50; tries++) {
+ lock();
+ getValues();
+ unlock();
+ if (containsPortInfo) {
+ Log.debug("Found valid values in port file after waiting "+(tries*100)+"ms");
+ return true;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e)
+ {}
+ }
+ Log.debug("Gave up waiting for valid values in port file");
+ return false;
+ }
+
+ /**
+ * Check if the portfile still contains my values, assuming that I am the server.
+ */
+ public synchronized boolean stillMyValues() throws IOException, FileNotFoundException {
+ for (;;) {
+ try {
+ lock();
+ getValues();
+ unlock();
+ if (containsPortInfo) {
+ if (serverPort == myServerPort &&
+ serverCookie == myServerCookie) {
+ // Everything is ok.
+ return true;
+ }
+ // Someone has overwritten the port file.
+ // Probably another javac server, lets quit.
+ return false;
+ }
+ // Something else is wrong with the portfile. Lets quit.
+ return false;
+ } catch (FileLockInterruptionException e) {
+ continue;
+ }
+ catch (ClosedChannelException e) {
+ // The channel has been closed since sjavac is exiting.
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Return the name of the port file.
+ */
+ public String getFilename() {
+ return filename;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/SysInfo.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/**
+ * A utility class used to report information about the system
+ * where the javac server is running.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+package com.sun.tools.sjavac.server;
+
+public class SysInfo {
+ public int numCores;
+ public long maxMemory;
+
+ public SysInfo(int nc, long mm) {
+ numCores = nc;
+ maxMemory = mm;
+ }
+}
--- a/langtools/src/share/classes/javax/lang/model/SourceVersion.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/SourceVersion.java Sat Jan 26 19:24:46 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
--- a/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Sat Jan 26 19:24:46 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
@@ -61,6 +61,18 @@
* parameters, return type, etc. rather than one of the abstract
* classes.
*
+ * <p>Note that methods to accommodate new language constructs could
+ * be added in a source <em>compatible</em> way if they were added as
+ * <em>default methods</em>. However, default methods are only
+ * available on Java SE 8 and higher releases and the {@code
+ * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * also be runnable on Java SE 7. Therefore, default methods
+ * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * to cover Java SE 8 language features. However, default methods may
+ * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * packages that are only required to run on Java SE 8 and higher
+ * platform versions.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
* @author Joseph D. Darcy
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java Sat Jan 26 19:24:46 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
@@ -149,6 +149,56 @@
<A extends Annotation> A getAnnotation(Class<A> annotationType);
/**
+ * Returns an array of all of this element's annotation for the
+ * specified type if such annotations are present, else an empty
+ * array. The annotation may be either inherited or directly
+ * present on this element. This method will look through a container
+ * annotation (if present) if the supplied annotation type is
+ * repeatable.
+ *
+ * <p> The annotations 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}.
+ *
+ * <blockquote>
+ * <i>Note:</i> 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.
+ * </blockquote>
+ *
+ * @param <A> the annotation type
+ * @param annotationType the {@code Class} object corresponding to
+ * the annotation type
+ * @return this element's annotations for the specified annotation
+ * type if present on this element, else an empty array
+ *
+ * @see #getAnnotationMirrors()
+ * @see #getAnnotation(java.lang.Class)
+ * @see java.lang.reflect.AnnotatedElement#getAnnotations
+ * @see EnumConstantNotPresentException
+ * @see AnnotationTypeMismatchException
+ * @see IncompleteAnnotationException
+ * @see MirroredTypeException
+ * @see MirroredTypesException
+ */
+ <A extends Annotation> A[] getAnnotations(Class<A> annotationType);
+
+ /**
* Returns the modifiers of this element, excluding annotations.
* Implicit modifiers, such as the {@code public} and {@code static}
* modifiers of interface members, are included.
--- a/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, 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,18 @@
* parameters, return type, etc. rather than one of the abstract
* classes.
*
+ * <p>Note that methods to accommodate new language constructs could
+ * be added in a source <em>compatible</em> way if they were added as
+ * <em>default methods</em>. However, default methods are only
+ * available on Java SE 8 and higher releases and the {@code
+ * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * also be runnable on Java SE 7. Therefore, default methods
+ * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * to cover Java SE 8 language features. However, default methods may
+ * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * packages that are only required to run on Java SE 8 and higher
+ * platform versions.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java Sat Jan 26 19:24:46 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<? extends AnnotationMirror> getAnnotations();
+ TypeMirror getUnderlyingType();
+}
--- a/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Sat Jan 26 19:24:46 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<? extends TypeMirror> 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.
*
--- a/langtools/src/share/classes/javax/lang/model/type/TypeKind.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/type/TypeKind.java Sat Jan 26 19:24:46 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
--- a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java Sat Jan 26 19:24:46 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,18 @@
* parameters, return type, etc. rather than one of the abstract
* classes.
*
+ * <p>Note that methods to accommodate new language constructs could
+ * be added in a source <em>compatible</em> way if they were added as
+ * <em>default methods</em>. However, default methods are only
+ * available on Java SE 8 and higher releases and the {@code
+ * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * also be runnable on Java SE 7. Therefore, default methods
+ * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * to cover Java SE 8 language features. However, default methods may
+ * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * packages that are only required to run on Java SE 8 and higher
+ * platform versions.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
@@ -182,4 +194,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);
}
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Sat Jan 26 19:24:46 2013 -0800
@@ -54,6 +54,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Sat Jan 26 19:24:46 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
@@ -51,6 +51,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java Sat Jan 26 19:24:46 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
@@ -51,6 +51,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Sat Jan 26 19:24:46 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
@@ -53,6 +53,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Sat Jan 26 19:24:46 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
@@ -52,6 +52,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java Sat Jan 26 19:24:46 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
@@ -52,6 +52,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Sat Jan 26 19:24:46 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
@@ -49,6 +49,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
@@ -125,6 +134,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}
*
* <p> The default implementation of this method in {@code
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Sat Jan 26 19:24:46 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
@@ -49,6 +49,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java Sat Jan 26 19:24:46 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
@@ -49,6 +49,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java Sat Jan 26 19:24:46 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
@@ -67,6 +67,15 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java Sat Jan 26 19:24:46 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
@@ -65,6 +65,15 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java Sat Jan 26 19:24:46 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
@@ -65,6 +65,15 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Sat Jan 26 19:24:46 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
@@ -63,6 +63,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Sat Jan 26 19:24:46 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
@@ -58,6 +58,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java Sat Jan 26 19:24:46 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
@@ -58,6 +58,15 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Sat Jan 26 19:24:46 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
@@ -65,6 +65,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Sat Jan 26 19:24:46 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
@@ -62,6 +62,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java Sat Jan 26 19:24:46 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
@@ -61,6 +61,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Sat Jan 26 19:24:46 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
@@ -64,6 +64,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Sat Jan 26 19:24:46 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
@@ -61,6 +61,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Sat Jan 26 19:24:46 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
@@ -60,6 +60,15 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java Sat Jan 26 19:24:46 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
@@ -63,6 +63,15 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java Sat Jan 26 19:24:46 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
@@ -63,6 +63,15 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java Sat Jan 26 19:24:46 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
@@ -63,6 +63,15 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
+ * <p>Note that adding a default implementation of a new visit method
+ * in a visitor class will occur instead of adding a <em>default
+ * method</em> directly in the visitor interface since a Java SE 8
+ * language feature cannot be used to this version of the API since
+ * this version is required to be runnable on Java SE 7
+ * implementations. Future versions of the API that are only required
+ * to run on Java SE 8 and later may take advantage of default methods
+ * in this situation.
+ *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/share/classes/javax/lang/model/util/Types.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/Types.java Sat Jan 26 19:24:46 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<? extends AnnotationMirror> 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.
+ *
+ * <p> 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}.
+ *
+ * <blockquote>
+ * <i>Note:</i> 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.
+ * </blockquote>
+ *
+ * @param <A> 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 extends Annotation> A typeAnnotationOf(TypeMirror type, Class<A> 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.
+ *
+ * <p> 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}.
+ *
+ * <blockquote>
+ * <i>Note:</i> 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.
+ * </blockquote>
+ *
+ * @param <A> 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 extends Annotation> A receiverTypeAnnotationOf(ExecutableType type, Class<A> annotationType);
+
}
--- a/langtools/test/Makefile Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/Makefile Sat Jan 26 19:24:46 2013 -0800
@@ -272,6 +272,7 @@
@mkdir -p $(JTREG_OUTPUT_DIR)
JT_JAVA=$(JT_JAVA) $(JTREG) \
-J-Xmx512m \
+ -vmoption:-Xmx768m \
-a -ignore:quiet -v:fail,error,nopass \
-r:$(JTREG_OUTPUT_DIR)/JTreport \
-w:$(JTREG_OUTPUT_DIR)/JTwork \
--- a/langtools/test/com/sun/javadoc/5093723/T5093723.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java Sat Jan 26 19:24:46 2013 -0800
@@ -36,7 +36,7 @@
private static final String BUG_ID = "5093723";
private static final String[] ARGS = new String[] {
- "-d", BUG_ID + ".out", "-source", "5",
+ "-d", BUG_ID + ".out", "-source", "5", "-Xdoclint:none",
SRC_DIR + "/DocumentedClass.java",
SRC_DIR + "/UndocumentedClass.java"
};
--- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -60,6 +60,7 @@
String srcdir = System.getProperty("test.src", ".");
runJavadoc(new String[] {"-d", TMPDIR_STRING1,
+ "-Xdoclint:none",
"-overview", (srcdir + FS + "overview.html"),
"-header", "<A HREF=\"{@docroot}/package-list\">{@docroot}</A> <A HREF=\"{@docRoot}/help-doc\">{@docRoot}</A>",
"-sourcepath", srcdir,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java Sat Jan 26 19:24:46 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",
+ "<a name=\"annotation_type_element_detail\">"
+ }
+ };
+
+ 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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java Sat Jan 26 19:24:46 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 "";
+}
--- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Sat Jan 26 19:24:46 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
@@ -40,7 +40,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "C2.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C2.java"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java Sat Jan 26 19:24:46 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
@@ -222,19 +222,19 @@
private static final String[] ARGS1 =
new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
- "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS3 =
new String[] {
- "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS4 =
new String[] {
- "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
/**
* The entry point of the test.
--- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Sat Jan 26 19:24:46 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
@@ -40,7 +40,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
+ "-Xdoclint:none", "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java Sat Jan 26 19:24:46 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
@@ -32,6 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainedBy(ContainerSynthDoc.class)
+@Repeatable(ContainerSynthDoc.class)
public @interface ContaineeSynthDoc {
}
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java Sat Jan 26 19:24:46 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
@@ -32,7 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainerFor(ContaineeSynthDoc.class)
public @interface ContainerSynthDoc {
ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java Sat Jan 26 19:24:46 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
@@ -32,6 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainedBy(ContainerSynthNotDoc.class)
+@Repeatable(ContainerSynthNotDoc.class)
public @interface ContaineeSynthDoc {
}
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java Sat Jan 26 19:24:46 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
@@ -31,7 +31,6 @@
*
* @author Bhavesh Patel
*/
-@ContainerFor(ContaineeSynthDoc.class)
public @interface ContainerSynthNotDoc {
ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java Sat Jan 26 19:24:46 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
@@ -39,7 +39,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, 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
@@ -36,7 +36,7 @@
private static final String BUG_ID = "4496223-4496270-4618686-4720974-4812240-6253614-6253604";
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
};
/**
--- a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2002, 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
@@ -42,7 +42,7 @@
};
private static final String[][] NEGATED_TEST = NO_TEST;
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
};
/**
--- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Sat Jan 26 19:24:46 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
@@ -41,6 +41,7 @@
//Javadoc arguments.
private static final String[] ARGS =
new String[] {
+ "-Xdoclint:none",
"-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag",
"todo", "pkg1", "pkg2"
};
--- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 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
@@ -43,7 +43,7 @@
};
private static final String[][] NEGATED_TEST = NO_TEST;
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "C.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C.java"
};
/**
--- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -43,11 +43,11 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
};
private static final String[] ARGS2 = new String[] {
- "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
+ "-Xdoclint:none", "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
};
//Input for string search tests.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Sat Jan 26 19:24:46 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 <mali>
+ * @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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java Sat Jan 26 19:24:46 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<? extends @A @DA String> lst) {}
+}
+
+/** wildcard bound generic/array */
+class T0x1D<T> {
+ void m0x1D(List<? extends @A @DA List<int[]>> lst) {}
+}
+
+/** typecast */
+class T0x00 {
+ void m0x00(Long l1) {
+ Object l2 = (@A @DA Long) l1;
+ }
+}
+
+/** typecast generic/array */
+class T0x01<T> {
+ void m0x01(List<T> list) {
+ List<T> 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<String>();
+ }
+}
+
+/** 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<T, U> {
+ <@A @DA T, @A @DA U> void m0x20() {}
+}
+
+/** class type parameter */
+class T0x22<@A @DA T, @A @DA U> {
+}
+
+/** class type parameter bound */
+class T0x10<T extends @A @DA Cloneable> {
+}
+
+class T0x10A<T extends @A @DA Object> {
+}
+
+/** method type parameter bound */
+class T0x12<T> {
+ <T extends @A @DA Cloneable> void m0x12() {}
+}
+
+/** class type parameter bound generic/array */
+class T0x11<T extends List<@A @DA T>> {
+}
+
+/** method type parameter bound generic/array */
+class T0x13 {
+ static <T extends Comparable<@A @DA T>> T m0x13() {
+ return null;
+ }
+}
+
+/** class extends/implements generic/array */
+class T0x15<T> extends ArrayList<@A @DA T> {
+}
+
+/** type test (instanceof) generic/array */
+class T0x03<T> {
+ void m0x03(T typeObj, Object obj) {
+ boolean ok = obj instanceof String @A @DA [];
+ }
+}
+
+/** object creation (new) generic/array */
+class T0x05<T> {
+ void m0x05() {
+ new ArrayList<@A @DA T>();
+ }
+}
+
+/** local variable generic/array */
+class T0x09<T> {
+ void g() {
+ List<@A @DA String> l = null;
+ }
+
+ void a() {
+ String @A @DA [] as = null;
+ }
+}
+
+/** type argument in constructor call generic/array */
+class T0x19 {
+ <T> T0x19() {}
+
+ void g() {
+ new <List<@A @DA String>> T0x19();
+ }
+}
+
+/** type argument in method call generic/array */
+class T0x1B<T> {
+ void m0x1B() {
+ Collections.<T @A @DA []>emptyList();
+ }
+}
+
+/** type argument in constructor call */
+class T0x18<T> {
+ <T> T0x18() {}
+
+ void m() {
+ new <@A @DA Integer> T0x18();
+ }
+}
+
+/** type argument in method call */
+class T0x1A<T,U> {
+ public static <T, U> 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 {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,93 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8004832
+ * @summary Add new doclint package
+ * @build DocLintTester
+ * @run main DocLintTester -ref AnchorTest.out AnchorTest.java
+ */
+
+/** */
+public class AnchorTest {
+ // tests for <a name=value>
+
+ /**
+ * <a name=foo></a>
+ */
+ public void a_name_foo() { }
+
+ /**
+ * <a name=foo></a>
+ */
+ public void a_name_already_defined() { }
+
+ /**
+ * <a name=></a>
+ */
+ public void a_name_empty() { }
+
+ /**
+ * <a name=123 ></a>
+ */
+ public void a_name_invalid() { }
+
+ /**
+ * <a name ></a>
+ */
+ public void a_name_missing() { }
+
+ // tests for <a id=value>
+
+ /**
+ * <a id=a_id_foo></a>
+ */
+ public void a_id_foo() { }
+
+ /**
+ * <a id=foo></a>
+ */
+ public void a_id_already_defined() { }
+
+ /**
+ * <a id=></a>
+ */
+ public void a_id_empty() { }
+
+ /**
+ * <a id=123 ></a>
+ */
+ public void a_id_invalid() { }
+
+ /**
+ * <a id ></a>
+ */
+ public void a_id_missing() { }
+
+ // tests for id=value on non-<a> tags
+
+ /**
+ * <p id=p_id_foo>text</p>
+ */
+ public void p_id_foo() { }
+
+ /**
+ * <p id=foo>text</p>
+ */
+ public void p_id_already_defined() { }
+
+ /**
+ * <p id=>text</p>
+ */
+ public void p_id_empty() { }
+
+ /**
+ * <p id=123 >text</p>
+ */
+ public void p_id_invalid() { }
+
+ /**
+ * <p id >text</p>
+ */
+ public void p_id_missing() { }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,37 @@
+AnchorTest.java:19: error: anchor already defined: foo
+ * <a name=foo></a>
+ ^
+AnchorTest.java:24: error: invalid name for anchor: ""
+ * <a name=></a>
+ ^
+AnchorTest.java:29: error: invalid name for anchor: "123"
+ * <a name=123 ></a>
+ ^
+AnchorTest.java:34: error: no value given for anchor
+ * <a name ></a>
+ ^
+AnchorTest.java:46: error: anchor already defined: foo
+ * <a id=foo></a>
+ ^
+AnchorTest.java:51: error: invalid name for anchor: ""
+ * <a id=></a>
+ ^
+AnchorTest.java:56: error: invalid name for anchor: "123"
+ * <a id=123 ></a>
+ ^
+AnchorTest.java:61: error: no value given for anchor
+ * <a id ></a>
+ ^
+AnchorTest.java:73: error: anchor already defined: foo
+ * <p id=foo>text</p>
+ ^
+AnchorTest.java:78: error: invalid name for anchor: ""
+ * <p id=>text</p>
+ ^
+AnchorTest.java:83: error: invalid name for anchor: "123"
+ * <p id=123 >text</p>
+ ^
+AnchorTest.java:88: error: no value given for anchor
+ * <p id >text</p>
+ ^
+12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/CoverageExtras.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,71 @@
+/*
+ * 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 8006263
+ * @summary Supplementary test cases needed for doclint
+ */
+
+import com.sun.tools.doclint.Checker;
+import com.sun.tools.doclint.Entity;
+import com.sun.tools.doclint.HtmlTag;
+import com.sun.tools.doclint.Messages;
+import java.util.Objects;
+
+public class CoverageExtras {
+ public static void main(String... args) {
+ new CoverageExtras().run();
+ }
+
+ void run() {
+ check(HtmlTag.A, HtmlTag.valueOf("A"), HtmlTag.values());
+ check(HtmlTag.Attr.ABBR, HtmlTag.Attr.valueOf("ABBR"), HtmlTag.Attr.values());
+ check(HtmlTag.AttrKind.INVALID, HtmlTag.AttrKind.valueOf("INVALID"), HtmlTag.AttrKind.values());
+ check(HtmlTag.BlockType.BLOCK, HtmlTag.BlockType.valueOf("BLOCK"), HtmlTag.BlockType.values());
+ check(HtmlTag.EndKind.NONE, HtmlTag.EndKind.valueOf("NONE"), HtmlTag.EndKind.values());
+ check(HtmlTag.Flag.EXPECT_CONTENT, HtmlTag.Flag.valueOf("EXPECT_CONTENT"), HtmlTag.Flag.values());
+
+ check(Checker.Flag.TABLE_HAS_CAPTION, Checker.Flag.valueOf("TABLE_HAS_CAPTION"), Checker.Flag.values());
+
+ check(Entity.nbsp, Entity.valueOf("nbsp"), Entity.values());
+
+ check(Messages.Group.ACCESSIBILITY, Messages.Group.valueOf("ACCESSIBILITY"), Messages.Group.values());
+ }
+
+ <T extends Enum<T>> void check(T expect, T value, T[] values) {
+ if (!Objects.equals(expect, value)) {
+ error("Mismatch: '" + expect + "', '" + value + "'");
+ }
+ if (!Objects.equals(expect, values[0])) {
+ error("Mismatch: '" + expect + "', '" + values[0] + "'");
+ }
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- a/langtools/test/tools/doclint/DocLintTester.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/doclint/DocLintTester.java Sat Jan 26 19:24:46 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
@@ -26,6 +26,7 @@
import java.util.List;
import com.sun.tools.doclint.DocLint;
+import com.sun.tools.doclint.DocLint.BadArgs;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -45,6 +46,7 @@
public void run(String... args) throws Exception {
String testSrc = System.getProperty("test.src");
+ boolean badArgs = false;
File refFile = null;
List<String> opts = new ArrayList<String>();
List<File> files = new ArrayList<File>();
@@ -52,19 +54,25 @@
String arg = args[i];
if (arg.equals("-ref")) {
refFile = new File(testSrc, args[++i]);
+ } else if (arg.equals("-badargs")) {
+ badArgs = true;
} else if (arg.startsWith("-Xmsgs")) {
opts.add(arg);
+ } else if (arg.startsWith("-")) {
+ opts.add(arg);
+ if (i < args.length - 1 && !args[i+1].startsWith("-"))
+ opts.add(args[++i]);
} else
files.add(new File(testSrc, arg));
}
- check(opts, files, refFile);
+ check(opts, files, badArgs, refFile);
if (errors > 0)
throw new Exception(errors + " errors occurred");
}
- void check(List<String> opts, List<File> files, File refFile) throws Exception {
+ void check(List<String> opts, List<File> files, boolean expectBadArgs, File refFile) throws Exception {
List<String> args = new ArrayList<String>();
args.addAll(opts);
for (File file: files)
@@ -72,7 +80,14 @@
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- new DocLint().run(pw, args.toArray(new String[args.size()]));
+ try {
+ new DocLint().run(pw, args.toArray(new String[args.size()]));
+ if (expectBadArgs)
+ error("expected exception not thrown");
+ } catch (BadArgs e) {
+ if (!expectBadArgs)
+ error("unexpected exception caught: " + e);
+ }
pw.flush();
String out = normalizeNewlines(removeFileNames(sw.toString())).trim();
if (out != null)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006236
+ * @summary doclint: structural issue hidden
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EndTagsTest.java
+ * @run main DocLintTester -ref EndTagsTest.out EndTagsTest.java
+ */
+
+/** */
+public class EndTagsTest {
+ /** <p> <a name="a1"> text <img alt="image" src="image.png"> </a> </p> */
+ public void valid_all() { }
+
+ /** <p> <a name="a2"> text <img alt="image" src="image.png"> </a> */
+ public void valid_omit_optional_close() { }
+
+ /** </a> */
+ public void invalid_missing_start() { }
+
+ /** <p> </a> */
+ public void invalid_missing_start_2() { }
+
+ /** <p> text </p> </a> */
+ public void invalid_missing_start_3() { }
+
+ /** <img alt="image" src="image.png"> </img> */
+ public void invalid_end() { }
+
+ /** <invalid> </invalid> */
+ public void unknown_start_end() { }
+
+ /** <invalid> */
+ public void unknown_start() { }
+
+ /** </invalid> */
+ public void unknown_end() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,25 @@
+EndTagsTest.java:18: error: unexpected end tag: </a>
+ /** </a> */
+ ^
+EndTagsTest.java:21: error: unexpected end tag: </a>
+ /** <p> </a> */
+ ^
+EndTagsTest.java:24: error: unexpected end tag: </a>
+ /** <p> text </p> </a> */
+ ^
+EndTagsTest.java:27: error: invalid end tag: </img>
+ /** <img alt="image" src="image.png"> </img> */
+ ^
+EndTagsTest.java:30: error: unknown tag: invalid
+ /** <invalid> </invalid> */
+ ^
+EndTagsTest.java:30: error: unknown tag: invalid
+ /** <invalid> </invalid> */
+ ^
+EndTagsTest.java:33: error: unknown tag: invalid
+ /** <invalid> */
+ ^
+EndTagsTest.java:36: error: unknown tag: invalid
+ /** </invalid> */
+ ^
+8 errors
--- a/langtools/test/tools/doclint/HtmlTagsTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/doclint/HtmlTagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -54,5 +54,17 @@
* <i> </b> </i>
*/
public void end_unexpected() { }
+
+ /**
+ * <ul> text <li> ... </li> </ul>
+ */
+ public void text_not_allowed() { }
+
+ /**
+ * <ul> <b>text</b> <li> ... </li> </ul>
+ */
+ public void inline_not_allowed() { }
+
+
}
--- a/langtools/test/tools/doclint/HtmlTagsTest.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/doclint/HtmlTagsTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -34,5 +34,11 @@
HtmlTagsTest.java:54: warning: empty <i> tag
* <i> </b> </i>
^
-11 errors
+HtmlTagsTest.java:59: error: text not allowed in <ul> element
+ * <ul> text <li> ... </li> </ul>
+ ^
+HtmlTagsTest.java:64: error: tag not allowed here: <b>
+ * <ul> <b>text</b> <li> ... </li> </ul>
+ ^
+13 errors
1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006228
+ * @summary Doclint doesn't detect <code> {@code nested inline} </code>
+ * @build DocLintTester
+ * @run main DocLintTester -ref LiteralTest.out LiteralTest.java
+ */
+
+/** */
+public class LiteralTest {
+ /** <code> abc {@literal < & > } def </code> */
+ public void ok_literal_in_code() { }
+
+ /** <code> abc {@code < & > } def </code> */
+ public void bad_code_in_code() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,4 @@
+LiteralTest.java:14: warning: {@code} within <code>
+ /** <code> abc {@code < & > } def </code> */
+ ^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/AAA.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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 8006728
+ * @summary temporarily workaround jtreg problems for doclint tests in othervm
+ */
+
+// dummy test/class to be compiled before other tests in this directory
+// see JDK-8006730
+public class AAA {
+ public static void main(String... args) { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/BlockTagsTest.java Sat Jan 26 19:24:46 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.
+ */
+
+/*
+ * @test
+ * @bug 8006251
+ * @summary test block tags
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs BlockTagsTest.java
+ */
+
+/** */
+public class BlockTagsTest {
+ /**
+ * <blockquote> abc </blockquote>
+ * <center> abc </center>
+ * <div> abc </div>
+ * <dl> <dt> abc <dd> def </dl>
+ * <div> abc </div>
+ * <h1> abc </h1>
+ * <h2> abc </h2>
+ * <h3> abc </h3>
+ * <h4> abc </h4>
+ * <h5> abc </h5>
+ * <h6> abc </h6>
+ * <hr>
+ * <menu> <li> abc </menu>
+ * <noscript> </noscript>
+ * <ol> <li> abc </ol>
+ * <p> abc </p>
+ * <pre> abc </pre>
+ * <table summary="abc"> <tr> <td> </table>
+ * <ul> <li> abc </ul>
+ */
+ public void supportedTags() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/EntitiesTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,317 @@
+/*
+ * 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 8006263
+ * @summary Supplementary test cases needed for doclint
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EntitiesTest.java
+ * @run main DocLintTester -Xmsgs:html -ref EntitiesTest.out EntitiesTest.java
+ */
+
+/** */
+class EntitiesTest {
+
+ /**
+ *    
+ * ࡎ ࡎ ࡎ
+ */
+ void range_test() { }
+
+ /**
+ *  
+ * ¡ ¡
+ * ¢ ¢
+ * £ £
+ * ¤ ¤
+ * ¥ ¥
+ * ¦ ¦
+ * § §
+ * ¨ ¨
+ * © ©
+ * ª ª
+ * « «
+ * ¬ ¬
+ * ­ ­
+ * ® ®
+ * ¯ ¯
+ * ° °
+ * ± ±
+ * ² ²
+ * ³ ³
+ * ´ ´
+ * µ µ
+ * ¶ ¶
+ * · ·
+ * ¸ ¸
+ * ¹ ¹
+ * º º
+ * » »
+ * ¼ ¼
+ * ½ ½
+ * ¾ ¾
+ * ¿ ¿
+ * À À
+ * Á Á
+ * Â Â
+ * Ã Ã
+ * Ä Ä
+ * Å Å
+ * Æ Æ
+ * Ç Ç
+ * È È
+ * É É
+ * Ê Ê
+ * Ë Ë
+ * Ì Ì
+ * Í Í
+ * Î Î
+ * Ï Ï
+ * Ð Ð
+ * Ñ Ñ
+ * Ò Ò
+ * Ó Ó
+ * Ô Ô
+ * Õ Õ
+ * Ö Ö
+ * × ×
+ * Ø Ø
+ * Ù Ù
+ * Ú Ú
+ * Û Û
+ * Ü Ü
+ * Ý Ý
+ * Þ Þ
+ * ß ß
+ * à à
+ * á á
+ * â â
+ * ã ã
+ * ä ä
+ * å å
+ * æ æ
+ * ç ç
+ * è è
+ * é é
+ * ê ê
+ * ë ë
+ * ì ì
+ * í í
+ * î î
+ * ï ï
+ * ð ð
+ * ñ ñ
+ * ò ò
+ * ó ó
+ * ô ô
+ * õ õ
+ * ö ö
+ * ÷ ÷
+ * ø ø
+ * ù ù
+ * ú ú
+ * û û
+ * ü ü
+ * ý ý
+ * þ þ
+ * ÿ ÿ
+ * ƒ ƒ
+ * Α Α
+ * Β Β
+ * Γ Γ
+ * Δ Δ
+ * Ε Ε
+ * Ζ Ζ
+ * Η Η
+ * Θ Θ
+ * Ι Ι
+ * Κ Κ
+ * Λ Λ
+ * Μ Μ
+ * Ν Ν
+ * Ξ Ξ
+ * Ο Ο
+ * Π Π
+ * Ρ Ρ
+ * Σ Σ
+ * Τ Τ
+ * Υ Υ
+ * Φ Φ
+ * Χ Χ
+ * Ψ Ψ
+ * Ω Ω
+ * α α
+ * β β
+ * γ γ
+ * δ δ
+ * ε ε
+ * ζ ζ
+ * η η
+ * θ θ
+ * ι ι
+ * κ κ
+ * λ λ
+ * μ μ
+ * ν ν
+ * ξ ξ
+ * ο ο
+ * π π
+ * ρ ρ
+ * ς ς
+ * σ σ
+ * τ τ
+ * υ υ
+ * φ φ
+ * χ χ
+ * ψ ψ
+ * ω ω
+ * ϑ ϑ
+ * ϒ ϒ
+ * ϖ ϖ
+ * • •
+ * … …
+ * ′ ′
+ * ″ ″
+ * ‾ ‾
+ * ⁄ ⁄
+ * ℘ ℘
+ * ℑ ℑ
+ * ℜ ℜ
+ * ™ ™
+ * ℵ ℵ
+ * ← ←
+ * ↑ ↑
+ * → →
+ * ↓ ↓
+ * ↔ ↔
+ * ↵ ↵
+ * ⇐ ⇐
+ * ⇑ ⇑
+ * ⇒ ⇒
+ * ⇓ ⇓
+ * ⇔ ⇔
+ * ∀ ∀
+ * ∂ ∂
+ * ∃ ∃
+ * ∅ ∅
+ * ∇ ∇
+ * ∈ ∈
+ * ∉ ∉
+ * ∋ ∋
+ * ∏ ∏
+ * ∑ ∑
+ * − −
+ * ∗ ∗
+ * √ √
+ * ∝ ∝
+ * ∞ ∞
+ * ∠ ∠
+ * ∧ ∧
+ * ∨ ∨
+ * ∩ ∩
+ * ∪ ∪
+ * &_int; ∫
+ * ∴ ∴
+ * ∼ ∼
+ * ≅ ≅
+ * ≈ ≈
+ * ≠ ≠
+ * ≡ ≡
+ * ≤ ≤
+ * ≥ ≥
+ * ⊂ ⊂
+ * ⊃ ⊃
+ * ⊄ ⊄
+ * ⊆ ⊆
+ * ⊇ ⊇
+ * ⊕ ⊕
+ * ⊗ ⊗
+ * ⊥ ⊥
+ * ⋅ ⋅
+ * ⌈ ⌈
+ * ⌉ ⌉
+ * ⌊ ⌊
+ * ⌋ ⌋
+ * ⟨ 〈
+ * ⟩ 〉
+ * ◊ ◊
+ * ♠ ♠
+ * ♣ ♣
+ * ♥ ♥
+ * ♦ ♦
+ * " "
+ * & &
+ * < <
+ * > >
+ * Œ Œ
+ * œ œ
+ * Š Š
+ * š š
+ * Ÿ Ÿ
+ * ˆ ˆ
+ * ˜ ˜
+ *    
+ *    
+ *    
+ * ‌ ‌
+ * ‍ ‍
+ * ‎ ‎
+ * ‏ ‏
+ * – –
+ * — —
+ * ‘ ‘
+ * ’ ’
+ * ‚ ‚
+ * “ “
+ * ” ”
+ * „ „
+ * † †
+ * ‡ ‡
+ * ‰ ‰
+ * ‹ ‹
+ * › ›
+ * € €
+ */
+ void symbolic_entities() { }
+
+ /**
+ * &bad;
+ */
+ void bad_name() { }
+
+ /**
+ * 
+ * ࡏ
+ */
+ void out_of_range() { }
+
+ /**
+ * ―
+ * ⌫
+ * 
+ */
+ void sparse_negative() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/EntitiesTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,19 @@
+EntitiesTest.java:300: error: invalid entity &bad;
+ * &bad;
+ ^
+EntitiesTest.java:305: error: invalid entity 
+ * 
+ ^
+EntitiesTest.java:306: error: invalid entity ࡏ
+ * ࡏ
+ ^
+EntitiesTest.java:311: error: invalid entity ―
+ * ―
+ ^
+EntitiesTest.java:312: error: invalid entity ⌫
+ * ⌫
+ ^
+EntitiesTest.java:313: error: invalid entity 
+ * 
+ ^
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/InlineTagsTest.java Sat Jan 26 19:24:46 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.
+ */
+
+/*
+ * @test
+ * @bug 8006251
+ * @summary test inline tags
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs InlineTagsTest.java
+ */
+
+/** */
+public class InlineTagsTest {
+ /**
+ * <a href="#abc"> abc </a>
+ * <b> abc </b>
+ * <big> abc </big>
+ * <br>
+ * <cite> abc </cite>
+ * <code> abc </code>
+ * <em> abc </em>
+ * <font> abc </font>
+ * <i> abc </i>
+ * <img alt="image" src="image.png">
+ * <small> abc </small>
+ * <span> abc </span>
+ * <strong> abc </strong>
+ * <sub> abc </sub>
+ * <sup> abc </sup>
+ * <tt> abc </tt>
+ * <u> abc </u>
+ * <var> abc </var>
+ */
+ public void supportedTags() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/ListTagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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 8006251
+ * @summary test list tags
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs ListTagsTest.java
+ */
+
+/** */
+public class ListTagsTest {
+ /**
+ * <dl> <dt> abc <dd> def </dl>
+ * <ol> <li> abc </ol>
+ * <ul> <li> abc </ul>
+ */
+ public void supportedTags() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006251
+ * @summary test other tags
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs -ref OtherTagsTest.out OtherTagsTest.java
+ */
+
+/** */
+public class OtherTagsTest {
+ /**
+ * <body> <p> abc </body>
+ * <frame>
+ * <frameset> </frameset>
+ * <head> </head>
+ * <link>
+ * <meta>
+ * <noframes> </noframes>
+ * <script> </script>
+ * <title> </title>
+ */
+ public void knownInvalidTags() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,28 @@
+OtherTagsTest.java:13: error: element not allowed in documentation comments: <body>
+ * <body> <p> abc </body>
+ ^
+OtherTagsTest.java:14: error: element not allowed in documentation comments: <frame>
+ * <frame>
+ ^
+OtherTagsTest.java:15: error: element not allowed in documentation comments: <frameset>
+ * <frameset> </frameset>
+ ^
+OtherTagsTest.java:16: error: element not allowed in documentation comments: <head>
+ * <head> </head>
+ ^
+OtherTagsTest.java:17: error: element not allowed in documentation comments: <link>
+ * <link>
+ ^
+OtherTagsTest.java:18: error: element not allowed in documentation comments: <meta>
+ * <meta>
+ ^
+OtherTagsTest.java:19: error: element not allowed in documentation comments: <noframes>
+ * <noframes> </noframes>
+ ^
+OtherTagsTest.java:20: error: element not allowed in documentation comments: <script>
+ * <script> </script>
+ ^
+OtherTagsTest.java:21: error: element not allowed in documentation comments: <title>
+ * <title> </title>
+ ^
+9 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/TableTagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,44 @@
+/*
+ * 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 8006251
+ * @summary test table tags
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs TableTagsTest.java
+ */
+
+/** */
+public class TableTagsTest {
+ /**
+ * <table summary="abc"> <tr> <td> </table>
+ * <table summary="abc"> <tr> <th> </table>
+ * <table> <caption> abc </caption> <tr> <td> </table>
+ * <table summary="abc"> <thead> <tr> </thead> <tr> <td> </table>
+ * <table summary="abc"> <tbody> <tr> <td> </tbody> </table>
+ * <table summary="abc"> <tr> <td> <tfoot> <tr> </tfoot></table>
+ */
+ public void supportedTags() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/TagNotAllowed.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,30 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8004832
+ * @summary Add new doclint package
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref TagNotAllowed.out TagNotAllowed.java
+ */
+
+/**
+ * <dl> <b>abc</b> <dt> term </dt> <b>def</b> <dd> description </dd> <b>ghi</b> </dl>
+ * <ol> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ol>
+ * <ul> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ul>
+ *
+ * <table summary=description> <b>abc</b> </table>
+ * <table summary=description> <thead> <b>abc</b> </thead> </table>
+ * <table summary=description> <tbody> <b>abc</b> </tbody> </table>
+ * <table summary=description> <tfoot> <b>abc</b> </tfoot> </table>
+ * <table summary=description> <tr> <b>abc</b> </tr> </table>
+ *
+ * <pre>
+ * <img alt="image" src="image.png">
+ * <p> para </p>
+ * <big> text </big>
+ * <small> text </small>
+ * <sub> text </sub>
+ * <sup> text </sup>
+ * </pre>
+ */
+public class TagNotAllowed { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/TagNotAllowed.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,61 @@
+TagNotAllowed.java:11: error: tag not allowed here: <b>
+ * <dl> <b>abc</b> <dt> term </dt> <b>def</b> <dd> description </dd> <b>ghi</b> </dl>
+ ^
+TagNotAllowed.java:11: error: tag not allowed here: <b>
+ * <dl> <b>abc</b> <dt> term </dt> <b>def</b> <dd> description </dd> <b>ghi</b> </dl>
+ ^
+TagNotAllowed.java:11: error: tag not allowed here: <b>
+ * <dl> <b>abc</b> <dt> term </dt> <b>def</b> <dd> description </dd> <b>ghi</b> </dl>
+ ^
+TagNotAllowed.java:12: error: tag not allowed here: <b>
+ * <ol> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ol>
+ ^
+TagNotAllowed.java:12: error: tag not allowed here: <b>
+ * <ol> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ol>
+ ^
+TagNotAllowed.java:12: error: tag not allowed here: <b>
+ * <ol> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ol>
+ ^
+TagNotAllowed.java:13: error: tag not allowed here: <b>
+ * <ul> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ul>
+ ^
+TagNotAllowed.java:13: error: tag not allowed here: <b>
+ * <ul> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ul>
+ ^
+TagNotAllowed.java:13: error: tag not allowed here: <b>
+ * <ul> <b>abc</b> <li> item </li> <b>def</b> <li> item </li> <b>ghi</b> </ul>
+ ^
+TagNotAllowed.java:15: error: tag not allowed here: <b>
+ * <table summary=description> <b>abc</b> </table>
+ ^
+TagNotAllowed.java:16: error: tag not allowed here: <b>
+ * <table summary=description> <thead> <b>abc</b> </thead> </table>
+ ^
+TagNotAllowed.java:17: error: tag not allowed here: <b>
+ * <table summary=description> <tbody> <b>abc</b> </tbody> </table>
+ ^
+TagNotAllowed.java:18: error: tag not allowed here: <b>
+ * <table summary=description> <tfoot> <b>abc</b> </tfoot> </table>
+ ^
+TagNotAllowed.java:19: error: tag not allowed here: <b>
+ * <table summary=description> <tr> <b>abc</b> </tr> </table>
+ ^
+TagNotAllowed.java:22: error: tag not allowed here: <img>
+ * <img alt="image" src="image.png">
+ ^
+TagNotAllowed.java:23: error: tag not allowed here: <p>
+ * <p> para </p>
+ ^
+TagNotAllowed.java:24: error: tag not allowed here: <big>
+ * <big> text </big>
+ ^
+TagNotAllowed.java:25: error: tag not allowed here: <small>
+ * <small> text </small>
+ ^
+TagNotAllowed.java:26: error: tag not allowed here: <sub>
+ * <sub> text </sub>
+ ^
+TagNotAllowed.java:27: error: tag not allowed here: <sup>
+ * <sup> text </sup>
+ ^
+20 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/TextNotAllowed.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,32 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8004832
+ * @summary Add new doclint package
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref TextNotAllowed.out TextNotAllowed.java
+ */
+
+/**
+ * <dl> abc <dt> term </dt> def <dd> description </dd> ghi </dl>
+ * <ol> abc <li> item </li> def <li> item </li> ghi </ol>
+ * <ul> abc <li> item </li> def <li> item </li> ghi </ul>
+ *
+ * <table summary=description> abc </table>
+ * <table summary=description> <thead> abc </thead> </table>
+ * <table summary=description> <tbody> abc </tbody> </table>
+ * <table summary=description> <tfoot> abc </tfoot> </table>
+ * <table summary=description> <tr> abc </tr> </table>
+ *
+ * <dl> & <dt> term </dt> < <dd> description </dd> > </dl>
+ * <ol> & <li> item </li> < <li> item </li> > </ol>
+ * <ul> & <li> item </li> < <li> item </li> > </ul>
+ *
+ * <table summary=description> & </table>
+ * <table summary=description> <thead> & </thead> </table>
+ * <table summary=description> <tbody> & </tbody> </table>
+ * <table summary=description> <tfoot> & </tfoot> </table>
+ * <table summary=description> <tr> & </tr> </table>
+ *
+ */
+public class TextNotAllowed { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/html/TextNotAllowed.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,85 @@
+TextNotAllowed.java:11: error: text not allowed in <dl> element
+ * <dl> abc <dt> term </dt> def <dd> description </dd> ghi </dl>
+ ^
+TextNotAllowed.java:11: error: text not allowed in <dl> element
+ * <dl> abc <dt> term </dt> def <dd> description </dd> ghi </dl>
+ ^
+TextNotAllowed.java:11: error: text not allowed in <dl> element
+ * <dl> abc <dt> term </dt> def <dd> description </dd> ghi </dl>
+ ^
+TextNotAllowed.java:12: error: text not allowed in <ol> element
+ * <ol> abc <li> item </li> def <li> item </li> ghi </ol>
+ ^
+TextNotAllowed.java:12: error: text not allowed in <ol> element
+ * <ol> abc <li> item </li> def <li> item </li> ghi </ol>
+ ^
+TextNotAllowed.java:12: error: text not allowed in <ol> element
+ * <ol> abc <li> item </li> def <li> item </li> ghi </ol>
+ ^
+TextNotAllowed.java:13: error: text not allowed in <ul> element
+ * <ul> abc <li> item </li> def <li> item </li> ghi </ul>
+ ^
+TextNotAllowed.java:13: error: text not allowed in <ul> element
+ * <ul> abc <li> item </li> def <li> item </li> ghi </ul>
+ ^
+TextNotAllowed.java:13: error: text not allowed in <ul> element
+ * <ul> abc <li> item </li> def <li> item </li> ghi </ul>
+ ^
+TextNotAllowed.java:15: error: text not allowed in <table> element
+ * <table summary=description> abc </table>
+ ^
+TextNotAllowed.java:16: error: text not allowed in <thead> element
+ * <table summary=description> <thead> abc </thead> </table>
+ ^
+TextNotAllowed.java:17: error: text not allowed in <tbody> element
+ * <table summary=description> <tbody> abc </tbody> </table>
+ ^
+TextNotAllowed.java:18: error: text not allowed in <tfoot> element
+ * <table summary=description> <tfoot> abc </tfoot> </table>
+ ^
+TextNotAllowed.java:19: error: text not allowed in <tr> element
+ * <table summary=description> <tr> abc </tr> </table>
+ ^
+TextNotAllowed.java:21: error: text not allowed in <dl> element
+ * <dl> & <dt> term </dt> < <dd> description </dd> > </dl>
+ ^
+TextNotAllowed.java:21: error: text not allowed in <dl> element
+ * <dl> & <dt> term </dt> < <dd> description </dd> > </dl>
+ ^
+TextNotAllowed.java:21: error: text not allowed in <dl> element
+ * <dl> & <dt> term </dt> < <dd> description </dd> > </dl>
+ ^
+TextNotAllowed.java:22: error: text not allowed in <ol> element
+ * <ol> & <li> item </li> < <li> item </li> > </ol>
+ ^
+TextNotAllowed.java:22: error: text not allowed in <ol> element
+ * <ol> & <li> item </li> < <li> item </li> > </ol>
+ ^
+TextNotAllowed.java:22: error: text not allowed in <ol> element
+ * <ol> & <li> item </li> < <li> item </li> > </ol>
+ ^
+TextNotAllowed.java:23: error: text not allowed in <ul> element
+ * <ul> & <li> item </li> < <li> item </li> > </ul>
+ ^
+TextNotAllowed.java:23: error: text not allowed in <ul> element
+ * <ul> & <li> item </li> < <li> item </li> > </ul>
+ ^
+TextNotAllowed.java:23: error: text not allowed in <ul> element
+ * <ul> & <li> item </li> < <li> item </li> > </ul>
+ ^
+TextNotAllowed.java:25: error: text not allowed in <table> element
+ * <table summary=description> & </table>
+ ^
+TextNotAllowed.java:26: error: text not allowed in <thead> element
+ * <table summary=description> <thead> & </thead> </table>
+ ^
+TextNotAllowed.java:27: error: text not allowed in <tbody> element
+ * <table summary=description> <tbody> & </tbody> </table>
+ ^
+TextNotAllowed.java:28: error: text not allowed in <tfoot> element
+ * <table summary=description> <tfoot> & </tfoot> </table>
+ ^
+TextNotAllowed.java:29: error: text not allowed in <tr> element
+ * <table summary=description> <tr> & </tr> </table>
+ ^
+28 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/AAA.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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 8006728
+ * @summary temporarily workaround jtreg problems for doclint tests in othervm
+ */
+
+// dummy test/class to be compiled before other tests in this directory
+// see JDK-8006730
+public class AAA {
+ public static void main(String... args) { }
+}
+
--- a/langtools/test/tools/doclint/tidy/ParaInPre.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/doclint/tidy/ParaInPre.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,4 +1,4 @@
-ParaInPre.java:16: warning: unexpected use of <p> inside <pre> element
+ParaInPre.java:16: error: tag not allowed here: <p>
* <p>
^
-1 warning
+1 error
--- a/langtools/test/tools/doclint/tidy/TextNotAllowed.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/doclint/tidy/TextNotAllowed.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,19 +1,19 @@
TextNotAllowed.java:13: error: text not allowed in <table> element
* <table summary=description> abc </table>
- ^
+ ^
TextNotAllowed.java:14: error: text not allowed in <tbody> element
* <table summary=description> <tbody> abc </tbody> </table>
- ^
+ ^
TextNotAllowed.java:15: error: text not allowed in <tr> element
* <table summary=description> <tr> abc </tr> </table>
- ^
+ ^
TextNotAllowed.java:17: error: text not allowed in <dl> element
* <dl> abc </dl>
- ^
+ ^
TextNotAllowed.java:18: error: text not allowed in <ol> element
* <ol> abc </ol>
- ^
+ ^
TextNotAllowed.java:19: error: text not allowed in <ul> element
* <ul> abc </ul>
- ^
+ ^
6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/AAA.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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 8006728
+ * @summary temporarily workaround jtreg problems for doclint tests in othervm
+ */
+
+// dummy test/class to be compiled before other tests in this directory
+// see JDK-8006730
+public class AAA {
+ public static void main(String... args) { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/HelpTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006263
+ * @summary Supplementary test cases needed for doclint
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref HelpTest.out
+ * @run main DocLintTester -ref HelpTest.out -h
+ * @run main DocLintTester -ref HelpTest.out -help
+ * @run main DocLintTester -ref HelpTest.out --help
+ * @run main DocLintTester -ref HelpTest.out -usage
+ * @run main DocLintTester -ref HelpTest.out -?
+ */
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/HelpTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,43 @@
+Usage:
+ doclint [options] source-files...
+
+Options:
+ -Xmsgs
+ Same as -Xmsgs:all
+ -Xmsgs:values
+ Specify categories of issues to be checked, where 'values'
+ is a comma-separated list of any of the following:
+ reference show places where comments contain incorrect
+ references to Java source code elements
+ syntax show basic syntax errors within comments
+ html show issues with HTML tags and attributes
+ accessibility show issues for accessibility
+ missing show issues with missing documentation
+ all all of the above
+ Precede a value with '-' to negate it
+ Categories may be qualified by one of:
+ /public /protected /package /private
+ For positive categories (not beginning with '-')
+ the qualifier applies to that access level and above.
+ For negative categories (beginning with '-')
+ the qualifier applies to that access level and below.
+ If a qualifier is missing, the category applies to
+ all access levels.
+ For example, -Xmsgs:all,-syntax/private
+ This will enable all messages, except syntax errors
+ in the doc comments of private methods.
+ If no -Xmsgs options are provided, the default is
+ equivalent to -Xmsgs:all/protected, meaning that
+ all messages are reported for protected and public
+ declarations only.
+ -stats
+ Report statistics on the reported issues.
+ -h -help --help -usage -?
+ Show this message.
+
+The following javac options are also supported
+ -bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns
+
+To run doclint on part of a project, put the compiled classes for your
+project on the classpath (or bootclasspath), then specify the source files
+to be checked on the command line.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/MaxDiagsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006263
+ * @summary Supplementary test cases needed for doclint
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref MaxDiagsTest.out -Xmaxerrs 2 -Xmaxwarns 2 MaxDiagsTest.java
+ * @run main DocLintTester -badargs -Xmaxerrs
+ * @run main DocLintTester -badargs -Xmaxwarns
+ * @run main DocLintTester -badargs -Xmaxerrs two -Xmaxwarns two MaxDiagsTest.java
+ */
+
+public class MaxDiagsTest {
+ /**
+ * � � � �
+ */
+ public void errors() { }
+
+ /** 4 undocumented signature items */
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/MaxDiagsTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,14 @@
+MaxDiagsTest.java:13: warning: no comment
+public class MaxDiagsTest {
+ ^
+MaxDiagsTest.java:15: error: invalid entity �
+ * � � � �
+ ^
+MaxDiagsTest.java:15: error: invalid entity �
+ * � � � �
+ ^
+MaxDiagsTest.java:20: warning: no @param for a1
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+ ^
+2 errors
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/PathsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,136 @@
+/*
+ * 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 8006263
+ * @summary Supplementary test cases needed for doclint
+ */
+
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.doclint.DocLint.BadArgs;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.regex.Pattern;
+
+public class PathsTest {
+ public static void main(String... args) throws Exception {
+ new PathsTest().run();
+ }
+
+ void run() throws Exception {
+ String PS = File.pathSeparator;
+ writeFile("src1/p/A.java",
+ "package p; public class A { }");
+ compile("-d", "classes1", "src1/p/A.java");
+
+ writeFile("src2/q/B.java",
+ "package q; public class B extends p.A { }");
+ compile("-d", "classes2", "-classpath", "classes1", "src2/q/B.java");
+
+ writeFile("src/Test.java",
+ "/** &0; */ class Test extends q.B { }");
+
+ test("src/Test.java", "-sourcepath", "src1" + PS + "src2");
+ test("src/Test.java", "-classpath", "classes1" + PS + "classes2");
+ String sysBootClassPath = System.getProperty("sun.boot.class.path");
+ test("src/Test.java", "-bootclasspath",
+ sysBootClassPath + PS + "classes1" + PS + "classes2");
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ Pattern pkgNotFound = Pattern.compile("package [a-z]+ does not exist");
+ Pattern badHtmlEntity = Pattern.compile("bad HTML entity");
+
+ void test(String file, String pathOpt, String path) throws BadArgs, IOException {
+ System.err.println("test " + pathOpt);
+ String out1 = doclint("-Xmsgs", file);
+ if (!pkgNotFound.matcher(out1).find())
+ error("message not found: " + pkgNotFound);
+
+ String out2 = doclint("-Xmsgs", pathOpt, path, file);
+ if (pkgNotFound.matcher(out2).find())
+ error("unexpected message found: " + pkgNotFound);
+ if (!badHtmlEntity.matcher(out1).find())
+ error("message not found: " + badHtmlEntity);
+
+ try {
+ doclint("-Xmsgs", pathOpt);
+ error("expected exception not thrown");
+ } catch (BadArgs e) {
+ System.err.println(e);
+ }
+ }
+
+ void compile(String... args) {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-d")) {
+ new File(args[++i]).mkdirs();
+ break;
+ }
+ }
+
+ 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.isEmpty())
+ System.err.println(out);
+ if (rc != 0)
+ error("compilation failed: rc=" + rc);
+ }
+
+ String doclint(String... args) throws BadArgs, IOException {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ DocLint dl = new DocLint();
+ dl.run(pw, args);
+ pw.close();
+ String out = sw.toString();
+ if (!out.isEmpty())
+ System.err.println(out);
+ return out;
+ }
+
+ File writeFile(String path, String body) throws IOException {
+ File f = new File(path);
+ f.getParentFile().mkdirs();
+ try (FileWriter fw = new FileWriter(path)) {
+ fw.write(body);
+ }
+ return f;
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/RunTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,200 @@
+/*
+ * 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 8006263
+ * @summary Supplementary test cases needed for doclint
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.doclint.DocLint.BadArgs;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+public class RunTest {
+ static class SimpleSecurityManager extends SecurityManager {
+ boolean allowExit = false;
+
+ @Override
+ public void checkExit(int status) {
+ if (!allowExit)
+ throw new SecurityException("System.exit(" + status + ")");
+ }
+ @Override
+ public void checkPermission(Permission perm) { }
+
+ }
+
+ public static void main(String... args) throws Exception {
+ // if no security manager already installed, install one to
+ // prevent System.exit
+ SimpleSecurityManager secmgr = null;
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(secmgr = new SimpleSecurityManager() { });
+ }
+
+ try {
+ new RunTest().run();
+ } finally {
+ if (secmgr != null)
+ secmgr.allowExit = true;
+ }
+ }
+
+ void run() throws Exception {
+ testMain();
+ testRun();
+ testInit();
+ testArgsNoFiles();
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ void testMain() {
+ System.err.println("test main(String[])");
+ testMain(true, "-help");
+ testMain(false, "-unknownOption");
+ }
+
+ void testMain(boolean expectOK, String... args) {
+ try {
+ DocLint.main(args);
+ if (!expectOK)
+ error("expected SecurityException (from System.exit) not thrown");
+ } catch (SecurityException e) {
+ System.err.println(e);
+ if (expectOK)
+ error("unexpected SecurityException caught");
+ }
+ }
+
+ void testRun() throws BadArgs, IOException {
+ System.err.println("test run(String[])");
+ DocLint dl = new DocLint();
+ String[] args = { "-help" };
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ PrintStream prev = System.out;
+ try {
+ System.setOut(ps);
+ dl.run(args);
+ } finally {
+ System.setOut(prev);
+ }
+ ps.close();
+ String stdout = baos.toString();
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ dl.run(pw, args);
+ pw.close();
+ String direct = sw.toString();
+
+ if (!stdout.equals(direct)) {
+ error("unexpected output");
+ System.err.println("EXPECT>>" + direct + "<<");
+ System.err.println("FOUND>>" + stdout + "<<");
+ }
+ }
+
+ void testInit() {
+ System.err.println("test init");
+ DocLint dl = new DocLint();
+ String name = dl.getName();
+ if (!Objects.equals(name, "doclint"))
+ error("unexpected result for DocLint.getName()");
+
+ List<? extends JavaFileObject> files =
+ Arrays.asList(createFile("Test.java", "/** &0; */ class Test{ }"));
+ String[] goodArgs = { "-Xmsgs" };
+ testInit(true, goodArgs, files);
+
+ String[] badArgs = { "-unknown" };
+ testInit(false, badArgs, files);
+ }
+
+ void testInit(boolean expectOK, String[] args, List<? extends JavaFileObject> files) {
+ JavacTool javac = JavacTool.create();
+ JavacTask task = javac.getTask(null, null, null, null, null, files);
+ try {
+ DocLint dl = new DocLint();
+ dl.init(task, args, true);
+ if (!expectOK)
+ error("expected IllegalArgumentException not thrown");
+ task.call();
+ } catch (IllegalArgumentException e) {
+ System.err.println(e);
+ if (expectOK)
+ error("unexpected IllegalArgumentException caught");
+ }
+ }
+
+ void testArgsNoFiles() throws BadArgs, IOException {
+ System.err.println("test args, no files");
+ DocLint dl = new DocLint();
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ dl.run(pw, "-Xmsgs");
+ pw.close();
+ String out = sw.toString();
+
+ String expect = "no files given";
+ if (!Objects.equals(out.trim(), expect)) {
+ error("unexpected output");
+ System.err.println("EXPECT>>" + expect + "<<");
+ System.err.println("FOUND>>" + out + "<<");
+ }
+
+ }
+
+ JavaFileObject createFile(String name, final String body) {
+ return new SimpleJavaFileObject(URI.create(name), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return body;
+ }
+ };
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/StatsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006263
+ * @summary Supplementary test cases needed for doclint
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref StatsTest.out -stats -Xmsgs:all StatsTest.java
+ */
+
+// warning: missing comment
+public class StatsTest {
+ /**
+ * � � � �
+ */
+ public void errors() { }
+
+ /** 4 undocumented signature items */
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tool/StatsTest.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,43 @@
+StatsTest.java:11: warning: no comment
+public class StatsTest {
+ ^
+StatsTest.java:13: error: invalid entity �
+ * � � � �
+ ^
+StatsTest.java:13: error: invalid entity �
+ * � � � �
+ ^
+StatsTest.java:13: error: invalid entity �
+ * � � � �
+ ^
+StatsTest.java:13: error: invalid entity �
+ * � � � �
+ ^
+StatsTest.java:18: warning: no @param for a1
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+ ^
+StatsTest.java:18: warning: no @param for a2
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+ ^
+StatsTest.java:18: warning: no @return
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+ ^
+StatsTest.java:18: warning: no @throws for java.lang.Exception
+ public int warnings(int a1, int a2) throws Exception { return 0; }
+ ^
+By group...
+ 5: missing
+ 4: html
+
+By diagnostic kind...
+ 5: warning
+ 4: error
+
+By message kind...
+ 4: invalid entity &{0};
+ 2: no @param for {0}
+ 1: no @return
+ 1: no @throws for {0}
+ 1: no comment
+4 errors
+5 warnings
--- a/langtools/test/tools/javac/7129225/TestImportStar.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/7129225/TestImportStar.java Sat Jan 26 19:24:46 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.*
--- a/langtools/test/tools/javac/7129225/TestImportStar.ref Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/7129225/TestImportStar.ref Sat Jan 26 19:24:46 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
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234d_1.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234d_1.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.intersection.type: 1, T6722234d.A)
+T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.intersection.type: 1, T6722234d.A,java.lang.Object)
- compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, java.lang.Object,T6722234d.I1,T6722234d.I2)}
1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234d_2.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234d_2.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.intersection.type: 1, T6722234d.A)
+T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.intersection.type: 1, T6722234d.A,Object)
- compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, Object,I1,I2)}
1 error
--- a/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,14 +23,18 @@
/**
* @test
- * @bug 6769027
+ * @bug 6769027 8006694
* @summary Source line should be displayed immediately after the first diagnostic line
+ * temporarily workaround combo tests are causing time out in several platforms
* @author Maurizio Cimadamore
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
* @run main/othervm T6769027
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.regex.Matcher;
import javax.tools.*;
@@ -488,7 +492,7 @@
}
if (!msg.equals(errorLine)) {
- printInfo(msg, errorLine);
+// printInfo(msg, errorLine);
errCount.incrementAndGet();
}
}
--- a/langtools/test/tools/javac/T6873845.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/T6873845.java Sat Jan 26 19:24:46 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<String> args) throws Exception{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6985181.java Sat Jan 26 19:24:46 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;
+ }
+}
--- a/langtools/test/tools/javac/T7093325.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/T7093325.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 7093325
+ * @bug 7093325 8006694
* @summary Redundant entry in bytecode exception table
+ * temporarily workaround combo tests are causing time out in several platforms
* @library lib
* @build JavacTestingAbstractThreadedTest
- * @run main T7093325
+ * @run main/othervm T7093325
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.io.File;
import java.net.URI;
import java.util.Arrays;
@@ -171,8 +175,6 @@
gapsCount++;
}
- //System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
-
File compiledTest = new File(String.format("Test%s.class", id));
try {
ClassFile cf = ClassFile.read(compiledTest);
--- a/langtools/test/tools/javac/annotations/6881115/T6881115.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/6881115/T6881115.java Sat Jan 26 19:24:46 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</*308 @A(b = @B(b2 = 1, b2 = 2),
- b_arr = {@B(), @B(b2 = 1, b2 = 2)})*/ X> {}
+class T6881115<@A(b = @B(b2 = 1, b2 = 2),
+ b_arr = {@B(), @B(b2 = 1, b2 = 2)}) X> {}
--- a/langtools/test/tools/javac/annotations/6881115/T6881115.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/6881115/T6881115.out Sat Jan 26 19:24:46 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
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,11 +6,9 @@
* @compile/fail/ref=BaseAnnoAsContainerAnno.out -XDrawDiagnostics BaseAnnoAsContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(Foo.class)
-@ContainerFor(Foo.class)
+@Repeatable(Foo.class)
@interface Foo {
Foo[] value() default {};
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-BaseAnnoAsContainerAnno.java:15:11: compiler.err.cyclic.annotation.element
+BaseAnnoAsContainerAnno.java:13:11: compiler.err.cyclic.annotation.element
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Sat Jan 26 19:24:46 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
@@ -34,10 +34,9 @@
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Sat Jan 26 19:24:46 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
@@ -32,32 +32,29 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@Target(ElementType.TYPE)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foos {
Foo[] value();
}
-@ContainedBy(Bars.class)
+@Repeatable(Bars.class)
@Target(ElementType.TYPE)
@interface Bar {}
-@ContainerFor(Bar.class)
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@interface Bars {
Bar[] value();
}
-@ContainedBy(Bazs.class)
+@Repeatable(Bazs.class)
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@interface Baz {}
-@ContainerFor(Baz.class)
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@interface Bazs {
Baz[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java Sat Jan 26 19:24:46 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,17 +30,15 @@
* @compile ClassReaderDefault.java
* @compile SeparateCompile.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
public class ClassReaderDefault {
}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
int f() default 0;
}
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Sat Jan 26 19:24:46 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,15 +30,13 @@
* @run compile ContainerHasRepeatedContained.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {}
@Bar
@Bar
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,17 +6,14 @@
* @compile/fail/ref=CyclicAnnotation.out -XDrawDiagnostics CyclicAnnotation.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(Foo.class)
-@ContainerFor(Baz.class)
+@Repeatable(Foo.class)
@interface Baz {
Foo[] value() default {};
}
-@ContainedBy(Baz.class)
-@ContainerFor(Foo.class)
+@Repeatable(Baz.class)
@interface Foo{
Baz[] value() default {};
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,6 +1,2 @@
-CyclicAnnotation.java:12:1: compiler.err.invalid.container.wrong.containerfor: Foo, Baz
-CyclicAnnotation.java:13:1: compiler.err.invalid.container.wrong.containedby: Foo, Baz
-CyclicAnnotation.java:15:11: compiler.err.cyclic.annotation.element
-CyclicAnnotation.java:18:1: compiler.err.invalid.container.wrong.containerfor: Baz, Foo
-CyclicAnnotation.java:19:1: compiler.err.invalid.container.wrong.containedby: Baz, Foo
-5 errors
+CyclicAnnotation.java:13:11: compiler.err.cyclic.annotation.element
+1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java Sat Jan 26 19:24:46 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
@@ -29,13 +29,11 @@
* @compile DefaultCasePresent.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
String other() default "other-method";
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Sat Jan 26 19:24:46 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
@@ -39,12 +39,11 @@
@Bar("katt")
@Bar("lol")
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {
String value();
}
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=DocumentedContainerAnno.out -XDrawDiagnostics DocumentedContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
import java.lang.annotation.Documented;
@Documented
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-DocumentedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.documented: FooContainer, Foo
+DocumentedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.documented: FooContainer, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=InheritedContainerAnno.out -XDrawDiagnostics InheritedContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
import java.lang.annotation.Inherited;
@Inherited
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-InheritedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.inherited: FooContainer, Foo
+InheritedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.inherited: FooContainer, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Sat Jan 26 19:24:46 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
@@ -32,11 +32,10 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.TYPE)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-
-@ContainerFor(MissingContainedBy.class)
-@interface Foos {
- MissingContainedBy[] value();
-}
-
-public @interface MissingContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingContainer.out -XDrawDiagnostics MissingContainer.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy()
+@Repeatable()
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,4 @@
-MissingContainer.java:20:1: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:20:6: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:12:1: compiler.err.annotation.missing.default.value: java.lang.annotation.ContainedBy, value
-MissingContainer.java:15:1: compiler.err.invalid.container.wrong.containedby: Foo, FooContainer
-4 errors
+MissingContainer.java:18:1: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:18:6: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:11:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Repeatable, value
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@interface Foos {
- MissingContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface MissingContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingDefaultCase1.out -XDrawDiagnostics MissingDefaultCase1.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
String other(); // missing default clause
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase1.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase1.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase1.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase1.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingDefaultCase2.out -XDrawDiagnostics MissingDefaultCase2.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
Foo other(); // missing default clause and return type is an annotation
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase2.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase2.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase2.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase2.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingValueMethod.out -XDrawDiagnostics MissingValueMethod.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] values(); // wrong method name
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,4 +1,4 @@
-MissingValueMethod.java:20:1: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:20:6: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, values()
+MissingValueMethod.java:18:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:18:6: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:11:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java Sat Jan 26 19:24:46 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
@@ -29,19 +29,16 @@
* @compile MultiLevelRepeatableAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainedBy(FooContainerContainer.class)
-@ContainerFor(Foo.class)
+@Repeatable(FooContainerContainer.class)
@interface FooContainer {
Foo[] value();
}
-@ContainerFor(FooContainer.class)
@interface FooContainerContainer {
FooContainer[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java Sat Jan 26 19:24:46 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
@@ -29,25 +29,22 @@
* @compile MultipleAnnoMixedOrder.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {
int getNumbers();
}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
}
-@ContainedBy(BazContainer.class)
+@Repeatable(BazContainer.class)
@interface Baz {
String getStr();
}
-@ContainerFor(Baz.class)
@interface BazContainer {
Baz[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Sat Jan 26 19:24:46 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
@@ -34,17 +34,15 @@
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(FoosFoos.class)
-@ContainerFor(Foo.class)
+@Repeatable(FoosFoos.class)
@interface Foos {
Foo[] value();
}
-@ContainerFor(Foos.class)
@Retention(RetentionPolicy.RUNTIME)
@interface FoosFoos {
Foos[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
-NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
+NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
+NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Sat Jan 26 19:24:46 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,20 +30,18 @@
* @run compile RepMemberAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
public class RepMemberAnno {
@Bar("Apa") @Bar("Banan")
public void meh() {}
}
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {
String value();
}
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Sat Jan 26 19:24:46 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
@@ -34,21 +34,19 @@
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
public @interface RepSelfMemberAnno {
@RepSelfMemberAnno @RepSelfMemberAnno
String meh() default "banan";
}
-@ContainedBy(BarContainerContainer.class)
+@Repeatable(BarContainerContainer.class)
@Retention(RetentionPolicy.RUNTIME)
-@ContainerFor(RepSelfMemberAnno.class)
@interface BarContainer {
RepSelfMemberAnno[] value();
}
-@ContainerFor(BarContainer.class)
@Retention(RetentionPolicy.RUNTIME)
@interface BarContainerContainer {
BarContainer[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Sat Jan 26 19:24:46 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 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
@interface Foos {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java Sat Jan 26 19:24:46 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
@@ -31,10 +31,9 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-RepeatingTargetNotAllowed.java:44:5: compiler.err.invalid.containedby.annotation.incompatible.target: Foos, Foo
+RepeatingTargetNotAllowed.java:43:5: compiler.err.invalid.repeatable.annotation.incompatible.target: Foos, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Sat Jan 26 19:24:46 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
@@ -33,7 +33,6 @@
import java.lang.annotation.*;
-@ContainerFor(SelfRepeatingAnno.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foos {
SelfRepeatingAnno[] value();
@@ -42,7 +41,7 @@
@SelfRepeatingAnno
@Retention(RetentionPolicy.RUNTIME)
@SelfRepeatingAnno
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface SelfRepeatingAnno {}
public class SelfRepeatingAnnotations {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Sat Jan 26 19:24:46 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,10 +30,9 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface Foos {
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(UseWrongContainedBy.class)
-@interface Foos {
- UseWrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface UseWrongContainedBy {}
-
-@UseWrongContainedBy @UseWrongContainedBy
-@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- UseWrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface UseWrongContainerFor {}
-
-@UseWrongContainerFor @UseWrongContainerFor
-@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java Sat Jan 26 19:24:46 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.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongRepeatable.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+ UseWrongRepeatable[] value();
+}
+
+@Repeatable(Target.class)
+public @interface UseWrongRepeatable {}
+
+@UseWrongRepeatable @UseWrongRepeatable
+@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
- WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java Sat Jan 26 19:24:46 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=WrongReturnTypeForValue.out -XDrawDiagnostics WrongReturnTypeForValue.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {
int getNumbers();
}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo value(); // wrong return type
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,4 @@
-WrongReturnTypeForValue.java:22:1: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-WrongReturnTypeForValue.java:22:6: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-2 errors
+WrongReturnTypeForValue.java:20:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:20:6: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:11:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Sat Jan 26 19:24:46 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
@@ -163,9 +163,8 @@
String replaceStr = "/*"+type+"*/";
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
JavaFileObject pkgInfoFile = null;
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Sat Jan 26 19:24:46 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
@@ -115,24 +115,21 @@
switch(className) {
case "DeprecatedonBoth":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonBase":
- annoData.append(Helper.ContentVars.CONTAINERFOR.getVal())
- .append(Helper.ContentVars.CONTAINER.getVal())
+ annoData.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonContainer":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Sat Jan 26 19:24:46 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
@@ -93,17 +93,15 @@
switch(className) {
case "DocumentedonBothAnno":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DocumentedonContainer":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Sat Jan 26 19:24:46 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
@@ -34,15 +34,13 @@
public class Helper {
enum ContentVars {
- IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" +
- "\nimport java.lang.annotation.ContainerFor;\n"),
+ IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.Repeatable;\n"),
IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
"\nimport java.lang.annotation.RetentionPolicy;\n"),
- CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"),
- CONTAINERFOR("@ContainerFor(Foo.class)\n"),
+ REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"),
BASE("@interface Foo {}\n"),
REPEATABLEANNO("\n@Foo() @Foo()"),
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Sat Jan 26 19:24:46 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
@@ -94,17 +94,15 @@
switch(className) {
case "InheritedonBothAnno":
annoData.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "InheritedonBase":
annoData.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Sat Jan 26 19:24:46 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
@@ -120,7 +120,7 @@
new DiagnosticCollector<JavaFileObject>();
boolean ok = compileCode(className, contents, diagnostics);
- String expectedErrKey = "compiler.err.invalid.containedby" +
+ String expectedErrKey = "compiler.err.invalid.repeatable" +
".annotation.retention";
if (!shouldCompile && !ok) {
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
@@ -175,10 +175,9 @@
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
.append(Helper.ContentVars.IMPORTRETENTION.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(replacedRetCAVal)
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(replacedRetBaseVal)
.append(Helper.ContentVars.BASE.getVal());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java Sat Jan 26 19:24:46 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..., ?);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java Sat Jan 26 19:24:46 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 <R> void method() { }
+ };
+ }
+
+ Object f1 = new InnerClass() {
+ <R> void method() { }
+ };
+
+ Object f2 = new InnerClass() {
+ <@A R> void method() { }
+ };
+
+ Object f3 = new InnerClass(null) {
+ <R> void method() { }
+ };
+
+ Object f4 = new InnerClass(null) {
+ <@A R> void method() { }
+ };
+
+ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+ @interface A { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java Sat Jan 26 19:24:46 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<K extends @A Object> {
+ @A void voidMethod() { }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.METHOD})
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java Sat Jan 26 19:24:46 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<? extends @A String> lst) {}
+}
+
+/** wildcard bound generic/array */
+class T0x1D<T> {
+ void m0x1D(List<? extends @A List<int[]>> lst) {}
+}
+
+/** typecast */
+class T0x00 {
+ void m0x00(Long l1) {
+ Object l2 = (@A Long) l1;
+ }
+}
+
+/** typecast generic/array */
+class T0x01<T> {
+ void m0x01(List<T> list) {
+ List<T> 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<String>();
+ }
+}
+
+/** 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<T, U> {
+ <@A T, @A U> void m0x20() {}
+}
+
+/** class type parameter */
+class T0x22<@A T, @A U> {
+}
+
+/** class type parameter bound */
+class T0x10<T extends @A Object> {
+}
+
+/** method type parameter bound */
+class T0x12<T> {
+ <T extends @A Object> void m0x12() {}
+}
+
+/** class type parameter bound generic/array */
+class T0x11<T extends List<@A T>> {
+}
+
+
+/** method type parameter bound generic/array */
+class T0x13 {
+ static <T extends Comparable<@A T>> T m0x13() {
+ return null;
+ }
+}
+
+/** class extends/implements generic/array */
+class T0x15<T> extends ArrayList<@A T> {
+}
+
+/** type test (instanceof) generic/array */
+class T0x03<T> {
+ void m0x03(T typeObj, Object obj) {
+ boolean ok = obj instanceof String @A [];
+ }
+}
+
+/** object creation (new) generic/array */
+class T0x05<T> {
+ void m0x05() {
+ new ArrayList<@A T>();
+ }
+}
+
+/** local variable generic/array */
+class T0x09<T> {
+ void g() {
+ List<@A String> l = null;
+ }
+
+ void a() {
+ String @A [] as = null;
+ }
+}
+
+/** type argument in constructor call generic/array */
+class T0x19 {
+ <T> T0x19() {}
+
+ void g() {
+ new <List<@A String>> T0x19();
+ }
+}
+
+/** type argument in method call generic/array */
+class T0x1B<T> {
+ void m0x1B() {
+ Collections.<T @A []>emptyList();
+ }
+}
+
+/** type argument in constructor call */
+class T0x18<T> {
+ <T> T0x18() {}
+
+ void m() {
+ new <@A Integer> T0x18();
+ }
+}
+
+/** type argument in method call */
+class T0x1A<T,U> {
+ public static <T, U> 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 {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java Sat Jan 26 19:24:46 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<Name> elements = new HashSet<Name>();
+
+ @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<? extends TypeElement> 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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java Sat Jan 26 19:24:46 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<K extends @A Object> {
+ @A String @A [] field;
+
+ @A String test(@A TypeUseTarget<K> this, @A String param, @A String @A ... vararg) {
+ @A Object o = new @A String @A [3];
+ TypeUseTarget<@A String> target;
+ return (@A String) null;
+ }
+
+ <K> @A String genericMethod(K k) { return null; }
+ @Decl <K> @A String genericMethod1(K k) { return null; }
+ @A @Decl <K> String genericMethod2(K k) { return null; }
+ @Decl @A <K> String genericMethod3(K k) { return null; }
+ <K> @Decl String genericMethod4(K k) { return null; }
+ <K> @A @Decl String genericMethod5(K k) { return null; }
+}
+
+@A
+interface MyInterface { }
+
+@A
+@interface MyAnnotation { }
+
+@Target(ElementType.TYPE_USE)
+@interface A { }
+
+@interface Decl { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java Sat Jan 26 19:24:46 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<? extends JavaFileObject> f =
+ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java")));
+ JavacTask task = tool.getTask(out, fm, null, null, null, f);
+ Iterable<? extends CompilationUnitTree> trees = task.parse();
+ out.flush();
+
+ Scanner s = new Scanner();
+ for (CompilationUnitTree t: trees)
+ s.scan(t, null);
+
+ }
+
+ private static class Scanner extends TreeScanner<Void,Void> {
+ 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<? extends AnnotationTree> 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<String, Integer> expectedLocations = new HashMap<String, Integer>();
+
+ // 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 {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java Sat Jan 26 19:24:46 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<? extends JavaFileObject> f =
+ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayCreationTree.java")));
+ JavacTask task = tool.getTask(out, fm, null, null, null, f);
+ Iterable<? extends CompilationUnitTree> trees = task.parse();
+ out.flush();
+
+ Scanner s = new Scanner();
+ for (CompilationUnitTree t: trees)
+ s.scan(t, null);
+
+ }
+
+ private static class Scanner extends TreeScanner<Void,Void> {
+ 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<? extends AnnotationTree> 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<? extends AnnotationTree> 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 {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java Sat Jan 26 19:24:46 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<? extends JavaFileObject> f =
+ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayPositionConsistency.java")));
+ JavacTask task = tool.getTask(out, fm, null, null, null, f);
+ Iterable<? extends CompilationUnitTree> trees = task.parse();
+ out.flush();
+
+ Scanner s = new Scanner();
+ for (CompilationUnitTree t: trees)
+ s.scan(t, null);
+
+ }
+
+ private static class Scanner extends TreeScanner<Void,Void> {
+ 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<? extends AnnotationTree> 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<String> @C [] @B [] genfield1;
+ @A List<String> @C [] [] genfield2;
+ @A List<String> [] @B [] genfield3;
+ List<String> [] @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 {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java Sat Jan 26 19:24:46 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(); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java Sat Jan 26 19:24:46 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<T extends Object> {
+ * public T data = null;
+ * T getData() { return data;}
+ * String mtest( Test13<String> t){ return t.getData(); }
+ * public void test() {
+ * mtest( new Test13<@A @B String>() {
+ * 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 + "<T extends Object> {\n" +
+ " public T data = null;\n" +
+ " T getData() { return data;}\n" +
+ " String mtest( " + testname + "<String> t){ return t.getData(); }\n" +
+ " public void test() {\n" +
+ " mtest( new " + testname + "<_As_ _Bs_ String>() {\n" +
+ " void m1(List<_As_ _Bs_ ? extends _As_ _Bs_ Object> lst) {}\n" +
+ " void m2() throws_As_ _Bs_ Exception { }\n" +
+ " });\n" +
+ " }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1";
+ 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<List<String>, Integer> map =
+ * new HashMap<List< String>, Integer>();
+ * Map<List<String>,Integer> map2 = new HashMap<>();
+ * String test(Test2<T> this) { return null;}
+ * <T> 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<List<String>, Integer> map =\n" +
+ " new HashMap<List< String>, Integer>();\n" +
+ " Map<List<String>,Integer> map2 = new HashMap<>();\n" +
+ " String test(" + testname + "<T> this) { return null;}\n" +
+ " <T> String genericMethod(T t) { return null; }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n\n";
+ break;
+ case 6: // (repeating) annotations on type parameters, bounds and type arguments on method.
+ /*
+ * class Test14<T extends Object> {
+ * Map<List<String>, Integer> map =
+ * new HashMap<List<String>, Integer>();
+ * Map<List<String>, 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 + "<T extends Object> {\n" +
+ " Map<List<String>, Integer> map =\n" +
+ " new HashMap<List<String>, Integer>();\n" +
+ " Map<List<String>, Integer> map2 = new HashMap<>();\n" +
+ " String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" +
+ " <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n\n";
+ break;
+ case 7: // repeating annotations on type parameters, bounds and type arguments in method.
+ /*
+ * class Test7{
+ * <E extends Comparable> Map<List<E>, E > foo(E e) {
+ * class maptest <@A @B @D E> {
+ * Map<List<@A @B @D E>,@A @B @D E> getMap() {
+ * return new HashMap<List<E>,E>();
+ * }
+ * }
+ * return new maptest<E>().getMap();
+ * }
+ * Map<List<String>,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" +
+ " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+ " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest
+ " Map<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E> getMap() { \n" +
+ " return new HashMap<List<E>,E>();\n" +
+ " }\n" +
+ " }\n" +
+ " return new maptest<E>().getMap();\n" +
+ " }\n" +
+ " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1maptest";
+ break;
+ }
+ return imports + source;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java Sat Jan 26 19:24:46 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<T extends Object> {
+ * Map<List<String>, Integer> map =
+ * new HashMap<@A @B List<@A @B String>, @A @B Integer>();
+ * Map<List<String>, Integer> map2 = new @A @B HashMap<>();
+ * String test(Test2<T> this) { return null;}
+ * <T> String genericMethod(T t) { return null; }
+ * }
+ */
+ source = new String( source +
+ "// (repeating) annotations on type parameters, bounds and type arguments. \n" +
+ "class " + testname + "<T extends Object> {\n" +
+ " Map<List<String>, Integer> map =\n" +
+ " new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" +
+ " Map<List<String>, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" +
+ " String test(" + testname + "<T> this) { return null;}\n" +
+ " <T> String genericMethod(T t) { return null; }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ break;
+ case 9: // (repeating)annotations on type parameters of class, method return value in method.
+ /*
+ * class Test3{
+ * <E extends Comparable> Map<List<E>, E > foo(E e) {
+ * class maptest <E> {
+ * Map<List<E>,E> getMap() {
+ * Map<List<E>,E> Em = new HashMap<List<@A @B @D E>,@A @B @D E>();
+ * return Em;
+ * }
+ * }
+ * return new maptest<E>().getMap();
+ * }
+ * Map<List<String>,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" +
+ " <E extends Comparable> Map<List<E>, E > foo(E e) {\n" +
+ " class maptest <E> {\n" + // inner class $1maptest
+ " Map<List<E>,E> getMap() { \n" +
+ " Map<List<E>,E> Em = new HashMap<List<_As_ _Bs_ _Ds_ E>,_As_ _Bs_ _Ds_ E>();\n" +
+ " return Em;\n" +
+ " }\n" +
+ " }\n" +
+ " return new maptest<E>().getMap();\n" +
+ " }\n" +
+ " Map<List<String>,String> shm = foo(new String(\"hello\"));\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) +
+ "\n\n";
+ hasInnerClass=true;
+ innerClassname="$1maptest";
+ break;
+
+ }
+ return imports + source;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java Sat Jan 26 19:24:46 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<? extends @A Object> o = null;
+ o.toString();
+
+ @A String m;
+ if (false) {
+ @A String a;
+ @A String b = "m";
+ b.toString();
+ List<? extends @A Object> c = null;
+ c.toString();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java Sat Jan 26 19:24:46 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 {}
+ <E> Test(E e) {}
+
+ void test() {
+ new <@A String> Test(null);
+ new <@A List<@A String>> Test(null);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java Sat Jan 26 19:24:46 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;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java Sat Jan 26 19:24:46 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;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java Sat Jan 26 19:24:46 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<? extends @A Number> f;
+
+ List<? extends @A Object> test(List<? extends @A Number> p) {
+ List<? extends @A Object> l; // not counted... gets optimized away
+ return null;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.6
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.7
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+BadCast.java:10:19: compiler.err.illegal.start.of.type
+1 error
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java Sat Jan 26 19:24:46 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<Outer. @A Inner> g4;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,1 @@
+dummy
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+IncompleteArray.java:9:13: compiler.err.illegal.start.of.type
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+IncompleteVararg.java:10:19: compiler.err.illegal.start.of.type
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+IndexArray.java:10:15: compiler.err.illegal.start.of.expr
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java Sat Jan 26 19:24:46 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<String> l = null;
+ List<String> l1 = (List<String>)l;
+ List<String> 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<String> l3 = null;
+ List<String> l4 = (List<String>)l3;
+ List<String> l5 = (@A List<String>)l3;
+
+ List<@A String> l6 = null;
+ List<String> l7 = (List<String>)l6;
+ List<String> 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out Sat Jan 26 19:24:46 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<java.lang.String>
+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<java.lang.String>
+LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List<java.lang.String>
+LintCast.java:57:21: compiler.warn.redundant.cast: java.lang.Object
+LintCast.java:61:27: compiler.warn.redundant.cast: LintCast.Outer.Inner
+10 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java Sat Jan 26 19:24:46 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<T extends @UniqueInner Object> {
+ // 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 { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+StaticFields.java:10:17: compiler.err.illegal.start.of.expr
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java Sat Jan 26 19:24:46 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 <T> @A void method() { }
+}
+
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:11:26: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:11:12: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:10:12: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:11:31: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:10:17: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:10:17: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:11:43: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:11:29: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:10:29: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java Sat Jan 26 19:24:46 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<T extends @BrokenAnnotation.A Object> {
+ @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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,3 @@
+BrokenAnnotation.java:16:6: compiler.err.cant.resolve.location: kindname.class, Target, , , (compiler.misc.location: kindname.class, BrokenAnnotation<T>, null)
+BrokenAnnotation.java:15:34: compiler.err.annotation.type.not.applicable
+2 errors
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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<K extends @A(value = 2, value = 1) Object> {
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { int value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:9:56: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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<K extends @A @A Object> {
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java Sat Jan 26 19:24:46 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<K extends @A Object> {
+}
+
+@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE)
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:9:33: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java Sat Jan 26 19:24:46 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<K extends @A Object> {
+}
+
+@Target(ElementType.TYPE_USE)
+@interface A { int field(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:10:40: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:10:27: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:10:13: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:9:13: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java Sat Jan 26 19:24:46 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) {}
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java Sat Jan 26 19:24:46 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) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java Sat Jan 26 19:24:46 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<X> {
+ <Y> void m(Generics<Y> this) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:11:9: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:11:9: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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<K> {
+ DuplicateAnnotationValue<@A(value = 2, value = 1) String> l;
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { int value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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<K> {
+ DuplicateTypeAnno<@A @A String> l;
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java Sat Jan 26 19:24:46 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<K> {
+ InvalidLocation<@A String> l;
+}
+
+@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE)
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java Sat Jan 26 19:24:46 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<K> {
+ MissingAnnotationValue<@A String> l;
+}
+
+@interface A { int field(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:9:46: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:9:23: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:8:30: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java Sat Jan 26 19:24:46 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<K> {
+ DuplicateAnnotationValue<@A(value = 2, value = 1) ?> l;
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { int value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java Sat Jan 26 19:24:46 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<K> {
+ DuplicateTypeAnno<@A @A ?> l;
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java Sat Jan 26 19:24:46 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<K> {
+ InvalidLocation<@A ?> l;
+}
+
+@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE)
+@interface A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java Sat Jan 26 19:24:46 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<K> {
+ MissingAnnotationValue<@A ?> l;
+}
+
+@interface A { int field(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java Sat Jan 26 19:24:46 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 { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+Constructor.java:17:3: compiler.err.annotation.type.not.applicable
+1 error
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java Sat Jan 26 19:24:46 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<Object> c = @A Object.class;
+ }
+
+ Class<?> c = @A String.class;
+
+ Class<? extends @A String> 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+IncompleteArray.java:9:13: compiler.err.illegal.start.of.type
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+NotTypeUse.java:13:3: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java Sat Jan 26 19:24:46 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<T extends @A Object> extends @B LinkedList<T> implements @C List<T> {
+
+ 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<? extends @A String> c2 = null;
+ }
+
+ // Handle receiver annotations
+ // Handle annotations on a qualified identifier list
+ void test2(@C @D BasicTest<T> 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.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java Sat Jan 26 19:24:46 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<K> {}
+interface ParameterizedInterface<K> {}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java Sat Jan 26 19:24:46 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<K> { }
+
+class ExtendsBound<K extends @A String> { }
+class ExtendsGeneric<K extends @A Unannotated<@B String>> { }
+class TwoBounds<K extends @A String, V extends @B String> { }
+
+class Complex1<K extends @A String&Runnable> { }
+class Complex2<K extends String & @B Runnable> { }
+class ComplexBoth<K extends @A String & @A Runnable> { }
+
+class Outer {
+ void inner() {
+ class Unannotated<K> { }
+
+ class ExtendsBound<K extends @A String> { }
+ class ExtendsGeneric<K extends @A Unannotated<@B String>> { }
+ class TwoBounds<K extends @A String, V extends @B String> { }
+
+ class Complex1<K extends @A String&Runnable> { }
+ class Complex2<K extends String & @B Runnable> { }
+ class ComplexBoth<K extends @A String & @A Runnable> { }
+ }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java Sat Jan 26 19:24:46 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<String, String>();
+ new MyMap<@A String, @B(0) MyList<@A String>>();
+ }
+
+ void withArraysIn() {
+ new MyList<String[]>();
+ new MyList<@A String @B(0) [] @A []>();
+
+ new MyMap<@A String[], @B(0) MyList<@A String> @A []>();
+ }
+}
+
+class MyList<E> { }
+class MyMap<K, V> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { int value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java Sat Jan 26 19:24:46 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<String, String> unannotated;
+ Parameterized<@A String, String> firstTypeArg;
+ Parameterized<String, @A String> 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<String, String> unannotated = null;
+ public final Parameterized<@A String, String> firstTypeArg = null;
+ public final Parameterized<String, @A String> 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<K, V> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java Sat Jan 26 19:24:46 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<String, String> unannotated;
+ Parameterized<@A String, String> firstTypeArg;
+ Parameterized<String, @A String> 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<String, String> unannotated = null;
+ final Parameterized<@A String, String> firstTypeArg = null;
+ final Parameterized<String, @A String> 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<K, V> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java Sat Jan 26 19:24:46 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<String, String> unannotated() { return null; }
+ Parameterized<@A String, String> firstTypeArg() { return null; }
+ Parameterized<String, @A String> secondTypeArg() { return null; }
+ Parameterized<@A String, @B String> bothTypeArgs() { return null; }
+
+ Parameterized<@A Parameterized<@A String, @B String>, @B String>
+ nestedParameterized() { return null; }
+
+ public <T> @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<String, String> unannotated() { return null; }
+ public final Parameterized<@A String, String> firstTypeArg() { return null; }
+ public final Parameterized<String, @A String> 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<K, V> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java Sat Jan 26 19:24:46 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.<String, String>newMap();
+ this.<@A String, @B(0) MyList<@A String>>newMap();
+
+ MethodTypeArgs.<String, String>newMap();
+ MethodTypeArgs.<@A String, @B(0) MyList<@A String>>newMap();
+ }
+
+ void withArraysIn() {
+ this.<String[]>newList();
+ this.<@A String @B(0) [] @A []>newList();
+
+ this.<@A String[], @B(0) MyList<@A String> @A []>newMap();
+ }
+
+ static <E> void newList() { }
+ static <K, V> void newMap() { }
+}
+
+class MyList<E> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { int value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java Sat Jan 26 19:24:46 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 {
+ <K extends @A String> void methodExtends() {}
+ <K extends @A Parameterized<@B String>> void nestedExtends() {}
+ <K extends @A String, V extends @A Parameterized<@B String>> void dual() {}
+ <K extends String, V extends Parameterized<@B String>> void dualOneAnno() {}
+}
+
+class PublicModifiedMethods {
+ public final <K extends @A String> void methodExtends() {}
+ public final <K extends @A Parameterized<@B String>> void nestedExtends() {}
+ public final <K extends @A String, V extends @A Parameterized<@B String>> void dual() {}
+ public final <K extends String, V extends Parameterized<@B String>> void dualOneAnno() {}
+}
+
+class Parameterized<K> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java Sat Jan 26 19:24:46 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<String,String>.@B Entry<String,String> p4d) {}
+ // Illegal:
+ // void m4d(@A Map<String,String>.@B Entry<String,String> p4d) {}
+
+ void m4e(MyList<Map.Entry> p4e) {}
+ void m4f(MyList<Map.@B Entry> p4f) {}
+ // Illegal:
+ // void m4g(MyList<@A Map.Entry> p4e) {}
+ // void m4h(MyList<@A Map.@B Entry> p4f) {}
+
+ class GInner<X> {
+ class GInner2<Y, Z> {}
+ }
+
+ static class Static {}
+ static class GStatic<X, Y> {
+ static class GStatic2<Z> {}
+ }
+}
+
+class Test1 {
+ // Outer.GStatic<Object,Object>.GStatic2<Object> gs;
+ Outer.GStatic.@A GStatic2<Object> gsgood;
+ // TODO: add failing test
+ // Outer.@A GStatic.GStatic2<Object> gsbad;
+
+ MyList<@A Outer . @B Inner. @C Inner2> f;
+ @A Outer .GInner<Object>.GInner2<String, Integer> g;
+
+ // TODO: Make sure that something like this fails gracefully:
+ // MyList<java.@B lang.Object> 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<Outer.GInner<Object>.GInner2<Integer>> 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<Outer . @B Static> 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<Outer . @Cv("Data") Static> 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<Outer . @Cv("Data") Static> 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<Outer . @Cv("Data") Static> 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<Outer . @Cv("Data") Static> p7 = new MyList<Outer . @Cv("Data") Static>();
+ }
+}
+
+class MyList<K> { }
+
+
+@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(); }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java Sat Jan 26 19:24:46 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<String, String> a) {}
+ void firstTypeArg(Parameterized<@A String, String> a) {}
+ void secondTypeArg(Parameterized<String, @A String> 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<K, V> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java Sat Jan 26 19:24:46 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) { }
+ <T> void generic(@A DefaultUnmodified this) { }
+ void withException(@A DefaultUnmodified this) throws Exception { }
+ String nonVoid(@A DefaultUnmodified this) { return null; }
+ <T extends Runnable> void accept(@A DefaultUnmodified this, T r) throws Exception { }
+}
+
+class PublicModified {
+ public final void plain(@A PublicModified this) { }
+ public final <T> 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 <T extends Runnable> void accept(@A PublicModified this, T r) throws Exception { }
+}
+
+class WithValue {
+ void plain(@B("m") WithValue this) { }
+ <T> void generic(@B("m") WithValue this) { }
+ void withException(@B("m") WithValue this) throws Exception { }
+ String nonVoid(@B("m") WithValue this) { return null; }
+ <T extends Runnable> void accept(@B("m") WithValue this, T r) throws Exception { }
+}
+
+class WithFinal {
+ void plain(final @B("m") WithFinal this) { }
+ <T> 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; }
+ <T extends Runnable> 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<X> {
+ void test1(Generic1<X> this) {}
+ void test2(@A Generic1<X> this) {}
+ void test3(Generic1<@A X> this) {}
+ void test4(@A Generic1<@A X> this) {}
+}
+
+class Generic2<@A X> {
+ void test1(Generic2<X> this) {}
+ void test2(@A Generic2<X> this) {}
+ void test3(Generic2<@A X> this) {}
+ void test4(@A Generic2<@A X> this) {}
+}
+
+class Generic3<X extends @A Object> {
+ void test1(Generic3<X> this) {}
+ void test2(@A Generic3<X> this) {}
+ void test3(Generic3<@A X> this) {}
+ void test4(@A Generic3<@A X> this) {}
+}
+
+class Generic4<X extends @A Object> {
+ <Y> void test1(Generic4<X> this) {}
+ <Y> void test2(@A Generic4<X> this) {}
+ <Y> void test3(Generic4<@A X> this) {}
+ <Y> 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<S, T> {
+ class GenericInner<U, V> {
+ void none(GenericOuter<S, T>.GenericInner<U, V> this) {}
+ void outer(@A GenericOuter<S, T>.GenericInner<U, V> this) {}
+ void inner(GenericOuter<S, T>. @B("i") GenericInner<U, V> this) {}
+ void both(@A GenericOuter<S, T>.@B("i") GenericInner<U, V> this) {}
+
+ void innerOnlyNone(GenericInner<U, V> this) {}
+ void innerOnly(@A GenericInner<U, V> this) {}
+ }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { String value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java Sat Jan 26 19:24:46 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.<String @TA @TA [] @TA @TA [], MyList<@TA @TA String> @TA @TA []>newMap();
+ }
+
+ static <E> void newList() { }
+ static <K, V> void newMap() { }
+}
+
+class MyList<E> { }
+
+
+@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();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out Sat Jan 26 19:24:46 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java Sat Jan 26 19:24:46 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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java Sat Jan 26 19:24:46 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(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java Sat Jan 26 19:24:46 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<K> { }
+class OneAnnotated<@A K> { }
+class TwoAnnotated<@A K, @A V> { }
+class SecondAnnotated<K, @A V extends String> { }
+
+class TestMethods {
+ <K> void unannotated() { }
+ <@A K> void oneAnnotated() { }
+ <@A K, @B("m") V> void twoAnnotated() { }
+ <K, @A V extends @A String> void secondAnnotated() { }
+}
+
+class UnannotatedB<K> { }
+class OneAnnotatedB<@B("m") K> { }
+class TwoAnnotatedB<@B("m") K, @B("m") V> { }
+class SecondAnnotatedB<K, @B("m") V extends @B("m") String> { }
+
+class OneAnnotatedC<@C K> { }
+class TwoAnnotatedC<@C K, @C V> { }
+class SecondAnnotatedC<K, @C V extends String> { }
+
+@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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java Sat Jan 26 19:24:46 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) {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java Sat Jan 26 19:24:46 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<? extends @A String> l) { }
+ void wcSuper(MyList<? super @A String> l) { }
+
+ MyList<? extends @A String> returnWcExtends() { return null; }
+ MyList<? super @A String> returnWcSuper() { return null; }
+ MyList<? extends @A MyList<? super @B("m") String>> complex() { return null; }
+}
+
+class BoundWithValue {
+ void wcExtends(MyList<? extends @B("m") String> l) { }
+ void wcSuper(MyList<? super @B(value="m") String> l) { }
+
+ MyList<? extends @B("m") String> returnWcExtends() { return null; }
+ MyList<? super @B(value="m") String> returnWcSuper() { return null; }
+ MyList<? extends @B("m") MyList<? super @B("m") String>> 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<K> { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface A { }
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface B { String value(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java Sat Jan 26 19:24:46 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<Name> elements = new HashSet<Name>();
+
+ @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<? extends TypeElement> 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);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java Sat Jan 26 19:24:46 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 {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java Sat Jan 26 19:24:46 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 {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java Sat Jan 26 19:24:46 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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java Sat Jan 26 19:24:46 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<String, @TB String>{ } ";
+ }
+
+ @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<String, @TB String>{ } ";
+ }
+
+ @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<String, @TB String>{ } ";
+ }
+
+ @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; }}";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java Sat Jan 26 19:24:46 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<K extends @TA Map<String, @TB String>, 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<K extends @TG Object & @TA Map<String, @TB String>, 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<K extends @TA Map<String, @TB String>, 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<K extends @TA Map<String, @TB String>, 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<K extends @TG Object & @TA Map<String, @TB String>, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }";
+ }
+
+ @TADescription(annotation = "TA", type = METHOD_RETURN)
+ public String useInReturn1() {
+ return "class Test<T> { @TA T m() { throw new RuntimeException(); } }";
+ }
+
+ @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0})
+ public String useInReturn2() {
+ return "class Test<T> { 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<T> { 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(); } }";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Sat Jan 26 19:24:46 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) {}" +
+ " } }";
+ }
+ */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java Sat Jan 26 19:24:46 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 <test-name>");
+ 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<String, TypeAnnotation.Position> 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<TypeAnnotation> 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<String, TypeAnnotation.Position> expectedOf(Method m) {
+ TADescription ta = m.getAnnotation(TADescription.class);
+ TADescriptions tas = m.getAnnotation(TADescriptions.class);
+
+ if (ta == null && tas == null)
+ return null;
+
+ Map<String, TypeAnnotation.Position> result =
+ new HashMap<String, TypeAnnotation.Position>();
+
+ if (ta != null)
+ result.putAll(expectedOf(ta));
+
+ if (tas != null) {
+ for (TADescription a : tas.value()) {
+ result.putAll(expectedOf(a));
+ }
+ }
+
+ return result;
+ }
+
+ private Map<String, TypeAnnotation.Position> 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<Integer> wrapIntArray(int[] ints) {
+ List<Integer> list = new ArrayList<Integer>(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<X, Y> { class GInner<X, Y> {} }");
+ }
+
+ // 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";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java Sat Jan 26 19:24:46 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) { }" +
+ " }";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java Sat Jan 26 19:24:46 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;";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java Sat Jan 26 19:24:46 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<A, B> { class O3 { class Nested<X, Y> {} } } }" +
+ "void test(@TH O1.@TE O2<@TF String, @TG String>.@TD O3.@TA Nested<@TB String, @TC String> a) { } }";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java Sat Jan 26 19:24:46 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); }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java Sat Jan 26 19:24:46 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) { } } }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java Sat Jan 26 19:24:46 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<String, String>. @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<X, Y> { class GInner<X, Y> {} } " +
+ "class Test<K> { Set<GOuter<String, String>.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<? extends @TB GOuter<String, String>. @TC GInner<String, Object>> entrySet() { return null; }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TC", type = METHOD_RETURN,
+ genericLocation = { 3, 0, 2, 0, 1, 0 }),
+ })
+ public String methodReturnAsNestedWildcard4() {
+ return "Set<? extends GOuter<String, String>. @TC GInner<String, 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 methodReturnAsNestedWildcard5() {
+ return "Set<? extends @TB Outer. @TC Inner> 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<? extends GOuter<String, String>. @TC GInner<@TA String, @TB Object>> entrySet() { return null; }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java Sat Jan 26 19:24:46 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; }";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java Sat Jan 26 19:24:46 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 "<K extends @TA Map<String, @TB String>, 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 <K extends @TG Object & @TA Map<String, @TB String>, 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 <K extends @TA Map<String, @TB String>, 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 <K extends @TA List<String>, V extends @TB List<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 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<String, @TB String>, @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<String, @TB String>, @TG V extends @TC List<@TD List<@TE Object>>> void test(); }";
+ }
+
+ @TADescription(annotation = "TA", type = METHOD_RETURN)
+ public String useInReturn1() {
+ return "class Test { <T> @TA T m() { throw new RuntimeException(); } }";
+ }
+
+ @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0})
+ public String useInReturn2() {
+ return "class Test { <T> 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 { <T extends @TA Object> @TB T m() { throw new RuntimeException(); } }";
+ }
+
+ @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+ paramIndex = 0, genericLocation = {3, 0})
+ public String useInParam1() {
+ return "class Test { <T> 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<XB> {} " +
+ "interface IC<XC> {} " +
+ "class Test { <T extends @TA IB<IA> & @TB IC<IA>> 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<XB> {} " +
+ " interface IC<XC> {} " +
+ " <T extends @TA IB<IA> & @TB IC<IA>> 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<XC> {} " +
+ " <T extends @TA Test. @TB CB<@TC IA>> 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<XB> {} " +
+ " class CC<XC> {} " +
+ " interface ID<XD> {} " +
+ " <@TA T extends @TB Test.CC<@TC IA> & Test. @TD ID<@TE IA>> void m(T p) { throw new RuntimeException(); } }";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java Sat Jan 26 19:24:46 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(); } }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Sat Jan 26 19:24:46 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<java.util.@TA Map.Entry> 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<java.util.@TA Map. @TB Entry> a) { }";
+ }
+ */
+
+ @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+ genericLocation = {3, 0}, paramIndex = 0)
+ public String testParam1g() {
+ return "void test(List<java.util.Map. @TB 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 testParam2() {
+ return "void test(@TA GOuter<String,String>.@TB GInner<String,String> 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<String,String>.@TB GInner<String,String>> 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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<String,String>.@TB GInner<String,String> 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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<String,String>.@TB GInner<String,String> 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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<String,String>.@TB GInner<String,String> 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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<X> {\n" +
+ " class GInner2<Y, Z> {}\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<A, B> {\n" +
+ " class GInner<X> {\n" +
+ " class GInner2<Y, Z> {}\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<String, String>> 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 extends @TA Outer.@TB Inner> 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 "<X extends @TA GOuter<String,String>.@TB GInner<String,String>> 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<X> {\n" +
+ " class GInner2<Y, Z> {}\n" +
+ "}}\n\n" +
+ "class Test {\n" +
+ " <X extends @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @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<X> {\n" +
+ " class GInner2<Y, Z> {}\n" +
+ "}}\n\n" +
+ "class Test {\n" +
+ " <X extends List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @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<A, B> {\n" +
+ " class GInner<X> {\n" +
+ " class GInner2<Y, Z> {}\n" +
+ "}}\n\n" +
+ "class Test {\n" +
+ " <X extends List<@TA GOuter<@TB String, @TC List<@TD Object>> . @TE GInner<@TF List<@TG Object @TH[] @TI[]>>. @TJ GInner2<String, String>>> 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<Inner.@TA Inner2> 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<Test.@TA Inner.Inner2> 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<Test.Inner.@TA Inner2> f; }}";
+ }
+
+ @TADescription(annotation = "TA", type = FIELD,
+ genericLocation = {3, 0, 1, 0, 1, 0})
+ @TestClass("Test$Inner")
+ public String testUses3a() {
+ return "class Test { class Inner<A, B> { class Inner2<C, D>{}\n" +
+ " List<Test.Inner.@TA Inner2> f; }}";
+ }
+
+ @TADescription(annotation = "TA", type = FIELD,
+ genericLocation = {3, 0, 1, 0})
+ @TestClass("Test$Inner")
+ public String testUses3b() {
+ return "class Test { class Inner<A, B> { class Inner2<C, D>{}\n" +
+ " List<Test.@TA Inner.Inner2> 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<A, B> { class Inner2<C, D>{}\n" +
+ " List<Test.Inner<String, @TA Object>.Inner2<Test, Test>> 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<java.security.@TA ProtectionDomain> 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";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java Sat Jan 26 19:24:46 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 >()); }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java Sat Jan 26 19:24:46 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<TypeAnnotation> extendedAnnotationsOf(ClassFile cf) {
+ List<TypeAnnotation> annos = new ArrayList<TypeAnnotation>();
+ findAnnotations(cf, annos);
+ return annos;
+ }
+
+ /////////////////// Extract type annotations //////////////////
+ private static void findAnnotations(ClassFile cf, List<TypeAnnotation> 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<TypeAnnotation> annos) {
+ findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
+ findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
+ }
+
+ private static void findAnnotations(ClassFile cf, Field m, List<TypeAnnotation> 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<TypeAnnotation> 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<TypeAnnotation> 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<TypeAnnotation> 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<length; i++)
+ if (a[i] != a2[i] && a[i] != IGNORE_VALUE && a2[i] != IGNORE_VALUE)
+ return false;
+
+ return true;
+ }
+
+ public static boolean areEquals(TypeAnnotation.Position p1, TypeAnnotation.Position p2) {
+ if (p1 == p2)
+ return true;
+ if (p1 == null || p2 == null)
+ return false;
+
+ return ((p1.type == p2.type)
+ && (p1.location.equals(p2.location))
+ && areEquals(p1.offset, p2.offset)
+ && areEquals(p1.lvarOffset, p2.lvarOffset)
+ && areEquals(p1.lvarLength, p2.lvarLength)
+ && areEquals(p1.lvarIndex, p2.lvarIndex)
+ && areEquals(p1.bound_index, p2.bound_index)
+ && areEquals(p1.parameter_index, p2.parameter_index)
+ && areEquals(p1.type_index, p2.type_index)
+ && areEquals(p1.exception_index, p2.exception_index));
+ }
+
+ private static TypeAnnotation findAnnotation(String name, List<TypeAnnotation> 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<String, TypeAnnotation.Position> expectedAnnos,
+ List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry {
+ if (actualAnnos.size() != expectedAnnos.size()) {
+ throw new ComparisionException("Wrong number of annotations",
+ expectedAnnos,
+ actualAnnos);
+ }
+
+ for (Map.Entry<String, TypeAnnotation.Position> 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<String, TypeAnnotation.Position> expected;
+ public final List<TypeAnnotation> found;
+
+ public ComparisionException(String message) {
+ this(message, null, null);
+ }
+
+ public ComparisionException(String message, Map<String, TypeAnnotation.Position> expected, List<TypeAnnotation> 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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java Sat Jan 26 19:24:46 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.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java Sat Jan 26 19:24:46 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); }";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java Sat Jan 26 19:24:46 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
+
+}
--- a/langtools/test/tools/javac/api/EndPositions.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/api/EndPositions.java Sat Jan 26 19:24:46 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<Diagnostic<? extends JavaFileObject>> 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!");
}
--- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 8002099
+ * @bug 8002099 8006694
* @summary Add support for intersection types in cast expression
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main/timeout=360 IntersectionTypeCastTest
+ * @run main/othervm/timeout=360 IntersectionTypeCastTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
@@ -287,8 +291,7 @@
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
- Arrays.asList("-XDallowIntersectionTypes"),
- null, Arrays.asList(source));
+ null, null, Arrays.asList(source));
try {
ct.analyze();
} catch (Throwable ex) {
--- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -170,7 +170,7 @@
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
checkCount++;
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
- Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
+ null, null, Arrays.asList(source));
ct.parse();
if (diagChecker.errorFound) {
throw new Error("Unexpected parser error for source:\n" +
--- a/langtools/test/tools/javac/cast/intersection/model/Model01.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/cast/intersection/model/Model01.java Sat Jan 26 19:24:46 2013 -0800
@@ -27,7 +27,7 @@
* @summary Add support for intersection types in cast expression
* @library /tools/javac/lib
* @build JavacTestingAbstractProcessor ModelChecker
- * @compile -XDallowIntersectionTypes -processor ModelChecker Model01.java
+ * @compile -processor ModelChecker Model01.java
*/
import javax.lang.model.element.ElementKind;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static01.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * smoke test for static interface methods
+ * @compile -XDallowStaticInterfaceMethods Static01.java
+ */
+public class Static01 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface I {
+ public static void test() {
+ assertTrue(true);
+ }
+ }
+
+ public static void main(String[] args) {
+ I.test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static02.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * smoke test for static interface methods
+ * @compile/fail/ref=Static02.out -XDrawDiagnostics -XDallowStaticInterfaceMethods Static02.java
+ */
+class Static02 {
+
+ interface I {
+ public static void test() { }
+ }
+
+ public static void main(String[] args) {
+ I.test(); //ok
+ I i = new I() {};
+ i.test(); //no!
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static02.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+Static02.java:40:15: compiler.err.illegal.static.intf.meth.call: Static02.I
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * Smoke test for static interface method hiding
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+
+public class InterfaceMethodHidingTest {
+
+ static int checkCount = 0;
+
+ enum SignatureKind {
+ VOID_INTEGER("void m(Integer s)", "return;"),
+ STRING_INTEGER("String m(Integer s)", "return null;"),
+ VOID_STRING("void m(String s)", "return;"),
+ STRING_STRING("String m(String s)", "return null;");
+
+ String sigStr;
+ String retStr;
+
+ SignatureKind(String sigStr, String retStr) {
+ this.sigStr = sigStr;
+ this.retStr = retStr;
+ }
+
+ boolean overrideEquivalentWith(SignatureKind s2) {
+ switch (this) {
+ case VOID_INTEGER:
+ case STRING_INTEGER:
+ return s2 == VOID_INTEGER || s2 == STRING_INTEGER;
+ case VOID_STRING:
+ case STRING_STRING:
+ return s2 == VOID_STRING || s2 == STRING_STRING;
+ default:
+ throw new AssertionError("bad signature kind");
+ }
+ }
+ }
+
+ enum MethodKind {
+ VIRTUAL("", "#M #S;"),
+ STATIC("static", "#M #S { #BE; #R }"),
+ DEFAULT("default", "#M #S { #BE; #R }");
+
+ String modStr;
+ String methTemplate;
+
+ MethodKind(String modStr, String methTemplate) {
+ this.modStr = modStr;
+ this.methTemplate = methTemplate;
+ }
+
+ boolean inherithed() {
+ return this != STATIC;
+ }
+
+ static boolean overrides(MethodKind mk1, SignatureKind sk1, MethodKind mk2, SignatureKind sk2) {
+ return sk1 == sk2 &&
+ mk2.inherithed() &&
+ mk1 != STATIC;
+ }
+
+ String getBody(BodyExpr be, SignatureKind sk) {
+ return methTemplate.replaceAll("#BE", be.bodyExprStr)
+ .replaceAll("#R", sk.retStr)
+ .replaceAll("#M", modStr)
+ .replaceAll("#S", sk.sigStr);
+ }
+ }
+
+ enum BodyExpr {
+ NONE(""),
+ THIS("Object o = this");
+
+ String bodyExprStr;
+
+ BodyExpr(String bodyExprStr) {
+ this.bodyExprStr = bodyExprStr;
+ }
+
+ boolean allowed(MethodKind mk) {
+ return this == NONE ||
+ mk != MethodKind.STATIC;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (MethodKind mk1 : MethodKind.values()) {
+ for (SignatureKind sk1 : SignatureKind.values()) {
+ for (BodyExpr be1 : BodyExpr.values()) {
+ for (MethodKind mk2 : MethodKind.values()) {
+ for (SignatureKind sk2 : SignatureKind.values()) {
+ for (BodyExpr be2 : BodyExpr.values()) {
+ for (MethodKind mk3 : MethodKind.values()) {
+ for (SignatureKind sk3 : SignatureKind.values()) {
+ for (BodyExpr be3 : BodyExpr.values()) {
+ new InterfaceMethodHidingTest(mk1, mk2, mk3, sk1, sk2, sk3, be1, be2, be3).run(comp, fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ MethodKind mk1, mk2, mk3;
+ SignatureKind sk1, sk2, sk3;
+ BodyExpr be1, be2, be3;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ InterfaceMethodHidingTest(MethodKind mk1, MethodKind mk2, MethodKind mk3,
+ SignatureKind sk1, SignatureKind sk2, SignatureKind sk3, BodyExpr be1, BodyExpr be2, BodyExpr be3) {
+ this.mk1 = mk1;
+ this.mk2 = mk2;
+ this.mk3 = mk3;
+ this.sk1 = sk1;
+ this.sk2 = sk2;
+ this.sk3 = sk3;
+ this.be1 = be1;
+ this.be2 = be2;
+ this.be3 = be3;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "interface Sup {\n" +
+ " default void sup() { }\n" +
+ "}\n" +
+ "interface A extends Sup {\n" +
+ " #M1\n" +
+ "}\n" +
+ "interface B extends A, Sup {\n" +
+ " #M2\n" +
+ "}\n" +
+ "interface C extends B, Sup {\n" +
+ " #M3\n" +
+ "}\n";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#M1", mk1.getBody(be1, sk1))
+ .replaceAll("#M2", mk2.getBody(be2, sk2))
+ .replaceAll("#M3", mk3.getBody(be3, sk3));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ Arrays.asList("-XDallowStaticInterfaceMethods"), null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected =
+ !be1.allowed(mk1) || !be2.allowed(mk2) || !be3.allowed(mk3);
+
+ if (mk1.inherithed()) {
+ errorExpected |=
+ sk2.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk2, sk2, mk1, sk1) ||
+ sk3.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk3, sk3, mk1, sk1);
+ }
+
+ if (mk2.inherithed()) {
+ errorExpected |=
+ sk3.overrideEquivalentWith(sk2) && !MethodKind.overrides(mk3, sk3, mk2, sk2);
+ }
+
+ checkCount++;
+ if (diagChecker.errorFound != errorExpected) {
+ throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
+ "\nfound error: " + diagChecker.errorFound);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport1.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * Smoke test for static imports of static interface methods
+ * @compile -XDallowStaticInterfaceMethods StaticImport1.java
+ */
+
+import static pkg.A.*;
+
+class StaticImport1 {
+ void test() {
+ m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * Smoke test for static imports of static interface methods
+ * @compile/fail/ref=StaticImport2.out -XDrawDiagnostics -XDallowStaticInterfaceMethods StaticImport2.java
+ */
+
+import static pkg.B.*;
+
+class StaticImport2 {
+ void test() {
+ m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+StaticImport2.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport2, null)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005166
+ * @summary Add support for static interface methods
+ * Smoke test for static imports of static interface methods
+ * @compile/fail/ref=StaticImport3.out -XDrawDiagnostics -XDallowStaticInterfaceMethods StaticImport3.java
+ */
+
+import static pkg.C.*;
+
+class StaticImport3 {
+ void test() {
+ m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+StaticImport3.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport3, null)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/A.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+public interface A {
+ static void m() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/B.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+public interface B extends A { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/C.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+public class C implements A { }
--- a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,17 +23,21 @@
/*
* @test
+ * @bug 8006694
* @summary Automatic test for checking correctness of default super/this resolution
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main TestDefaultSuperCall
+ * @run main/othervm TestDefaultSuperCall
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
@@ -212,7 +216,6 @@
List<String> elementsWithMethod;
Shape(ElementKind... elements) {
- errWriter.println("elements = " + Arrays.toString(elements));
enclosingElements = new ArrayList<>();
enclosingNames = new ArrayList<>();
elementsWithMethod = new ArrayList<>();
@@ -406,7 +409,6 @@
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
- errWriter.println(diagnostic.getMessage(Locale.getDefault()));
errorFound = true;
}
}
--- a/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7192245
+ * @bug 7192245 8005851 8005166
* @summary Automatic test for checking set of allowed modifiers on interface methods
*/
@@ -54,7 +54,7 @@
}
List<String> getOptions() {
- return Arrays.asList("-source", versionString);
+ return Arrays.asList("-XDallowStaticInterfaceMethods", "-source", versionString);
}
}
@@ -77,32 +77,6 @@
this.modStr = modStr;
}
- boolean isAllowed(EnclosingKind ek, ModifierKind otherMod) {
- if (this == otherMod) return false;
- switch (this) {
- case NONE:
- return true;
- case ABSTRACT:
- return otherMod != PRIVATE;
- case NATIVE:
- return otherMod != ABSTRACT &&
- otherMod != STRICTFP;
- case FINAL:
- case STATIC:
- case SYNCHRONIZED:
- case STRICTFP:
- return otherMod != ABSTRACT;
- case PUBLIC:
- return true;
- case PROTECTED:
- return ek == EnclosingKind.ABSTRACT_CLASS;
- case DEFAULT:
- return otherMod != ABSTRACT;
- default:
- return true;
- }
- }
-
static boolean intersect(ModifierKind mk, ModifierKind... mks) {
for (ModifierKind mk2 : mks) {
if (mk == mk2) return true;
@@ -113,7 +87,7 @@
static boolean compatible(MethodKind mk, ModifierKind mod1, ModifierKind mod2, EnclosingKind ek) {
if (intersect(ABSTRACT, mod1, mod2) || intersect(NATIVE, mod1, mod2)) {
return mk == MethodKind.NO_BODY;
- } else if (intersect(DEFAULT, mod1, mod2)) {
+ } else if (intersect(DEFAULT, mod1, mod2) || intersect(STATIC, mod1, mod2)) {
return mk == MethodKind.BODY;
} else {
return ek == EnclosingKind.INTERFACE ?
@@ -123,7 +97,6 @@
boolean compatible(EnclosingKind ek) {
switch (this) {
- case STATIC:
case PRIVATE:
case PROTECTED:
return ek != EnclosingKind.INTERFACE;
@@ -176,17 +149,17 @@
static Result[][] allowedModifierPairs = {
/* NONE PUBLIC PROTECTED PRIVATE ABSTRACT STATIC NATIVE SYNCHRONIZED FINAL STRICTFP DEFAULT */
- /* NONE */ { T , T , C , C , T , C , C , C , C , C , I },
- /* PUBLIC */ { T , F , F , F , T , C , C , C , C , C , I },
+ /* NONE */ { T , T , C , C , T , T , C , C , C , C , I },
+ /* PUBLIC */ { T , F , F , F , T , T , C , C , C , C , I },
/* PROTECTED */ { C , F , F , F , C , C , C , C , C , C , F },
/* PRIVATE */ { C , F , F , F , F , C , C , C , C , C , F },
/* ABSTRACT */ { T , T , C , F , F , F , F , F , F , F , F },
- /* STATIC */ { C , C , C , C , F , F , C , C , C , C , F },
+ /* STATIC */ { T , T , C , C , F , F , C , C , C , T , F },
/* NATIVE */ { C , C , C , C , F , C , F , C , C , F , F },
- /* SYNCHRONIZED */ { C , C , C , C , F , C , C , F , C , C , I },
+ /* SYNCHRONIZED */ { C , C , C , C , F , C , C , F , C , C , F },
/* FINAL */ { C , C , C , C , F , C , C , C , F , C , F },
- /* STRICTFP */ { C , C , C , C , F , C , F , C , C , F , I },
- /* DEFAULT */ { I , I , F , F , F , F , F , I , F , I , F }};
+ /* STRICTFP */ { C , C , C , C , F , T , F , C , C , F , I },
+ /* DEFAULT */ { I , I , F , F , F , F , F , F , F , I , F }};
}
enum MethodKind {
@@ -291,6 +264,9 @@
errorExpected |= ModifierKind.intersect(ModifierKind.DEFAULT, modk1, modk2) &&
vk == VersionKind.PRE_LAMBDA;
+ errorExpected |= ModifierKind.intersect(ModifierKind.STATIC, modk1, modk2) &&
+ ek == EnclosingKind.INTERFACE && vk == VersionKind.PRE_LAMBDA;
+
checkCount++;
if (diagChecker.errorFound != errorExpected) {
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Sat Jan 26 19:24:46 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<String> needToInvestigate = new TreeSet<String>(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
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Sat Jan 26 19:24:46 2013 -0800
@@ -1,13 +1,14 @@
compiler.err.already.annotated # internal compiler error?
compiler.err.already.defined.this.unit # seems to be masked by compiler.err.duplicate.class
compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests
+compiler.err.bad.functional.intf.anno # seems to be masked by compiler.err.annotation.type.not.applicable
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
compiler.err.dc.unterminated.string # cannot happen
compiler.err.illegal.char.for.encoding
-compiler.err.invalid.containedby.annotation # should not happen
-compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
-compiler.err.invalid.containedby.annotation.multiple.values # can't happen
+compiler.err.invalid.repeatable.annotation # should not happen
+compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen
+compiler.err.invalid.repeatable.annotation.multiple.values # can't happen
compiler.err.io.exception # (javah.JavahTask?)
compiler.err.limit.code # Code
compiler.err.limit.code.too.large.for.try.stmt # Gen
@@ -47,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
@@ -58,6 +60,7 @@
compiler.misc.fatal.err.cant.close # JavaCompiler
compiler.misc.file.does.not.contain.package
compiler.misc.illegal.start.of.class.file
+compiler.misc.inferred.do.not.conform.to.lower.bounds # cannot happen?
compiler.misc.kindname.annotation
compiler.misc.kindname.enum
compiler.misc.kindname.package
@@ -67,6 +70,7 @@
compiler.misc.kindname.value
compiler.misc.incompatible.eq.lower.bounds # cannot happen?
compiler.misc.no.unique.minimal.instance.exists
+compiler.misc.no.unique.maximal.instance.exists # cannot happen?
compiler.misc.resume.abort # prompt for a response
compiler.misc.source.unavailable # DiagnosticSource
compiler.misc.token.bad-symbol
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.bad.functional.intf.anno.1
+// key: compiler.misc.not.a.functional.intf
+
+@FunctionalInterface
+class BadFunctionalIntfAnno { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java Sat Jan 26 19:24:46 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;
+}
--- a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.documented
-
-import java.lang.annotation.*;
-
-@Documented
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByDocumentedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.inherited
-
-import java.lang.annotation.*;
-
-@Inherited
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByInheritedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.no.value
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos {}
-
-@Anno
-@Anno
-class ContainedByNoValue { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); String foo(); }
-
-class ContainedByNonDefault { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.retention
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByRetentionMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.incompatible.target
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@Target(ElementType.METHOD)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-class ContainedByTargetMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.value.return
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { String value(); }
-
-@Anno
-@Anno
-class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/CyclicInference.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples/CyclicInference.java Sat Jan 26 19:24:46 2013 -0800
@@ -21,7 +21,7 @@
* questions.
*/
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.prob.found.req
// key: compiler.misc.cyclic.inference
class CyclicInference {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IllegalStaticIntfMethCall.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.illegal.static.intf.meth.call
+// options: -XDallowStaticInterfaceMethods
+
+class IllegalStaticIntfMethCall {
+ interface A {
+ static void m() { }
+ }
+ void test(A a) {
+ a.m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java Sat Jan 26 19:24:46 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) {}
+}
--- a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToLower.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.inferred.do.not.conform.to.lower.bounds
-
-import java.util.*;
-
-class InferredDoNotConformToLower {
- <X extends Number> List<X> m() { return null; }
- { List<? super String> lss = this.m(); }
-}
--- a/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java Sat Jan 26 19:24:46 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
@@ -22,17 +22,16 @@
*/
// key: compiler.err.duplicate.annotation.invalid.repeated
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-//
+// key: compiler.err.invalid.repeatable.annotation.elem.nondefault
+
// We need an almost valid containing annotation. The easiest way to get
// one close enough to valid is by forgetting a default.
import java.lang.annotation.*;
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
@interface Anno { }
-@ContainerFor(Anno.class)
@interface Annos { Anno[] value(); String foo(); }
@Anno
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java Sat Jan 26 19:24:46 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;
+}
--- a/langtools/test/tools/javac/diags/examples/NoUniqueMaximalInstance.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.no.unique.maximal.instance.exists
-
-class NoUniqueMaximalInstance {
- <Z extends Integer> Z m() { return null; }
-
- { String s = m(); }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * 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.invalid.repeatable.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableDocumentedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * 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.invalid.repeatable.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableInheritedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNoValue.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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.invalid.repeatable.annotation.no.value
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos {}
+
+@Anno
+@Anno
+class RepeatableNoValue { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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.invalid.repeatable.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); String foo(); }
+
+class RepeatableNonDefault { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * 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.invalid.repeatable.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableRetentionMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,34 @@
+/*
+ * 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.invalid.repeatable.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+class RepeatableTargetMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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.invalid.repeatable.annotation.value.return
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class RepeatableWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Sat Jan 26 19:24:46 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
@@ -21,14 +21,13 @@
* questions.
*/
-// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+// key: compiler.err.invalid.repeatable.annotation.repeated.and.container.present
import java.lang.annotation.*;
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
@interface Anno { }
-@ContainerFor(Anno.class)
@interface Annos { Anno[] value(); }
@Anno
--- a/langtools/test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.secondary.bound.must.be.marker.intf
-// options: -XDallowIntersectionTypes
class SecondaryBoundMustBeMarkerInterface {
Runnable r = (Runnable & Comparable<?>)()->{};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/StaticIntfMethodNotSupported.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.static.intf.methods.not.supported.in.source
+// options: -source 7 -Xlint:-options -XDallowStaticInterfaceMethods
+
+interface StaticIntfMethodNotSupported {
+ static void m() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Sat Jan 26 19:24:46 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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnderscoreAsIdentifier.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.underscore.as.identifier
+
+class UnderscoreAsIdentifier {
+ String _ = null;
+}
--- a/langtools/test/tools/javac/diags/examples/WhereIntersection.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/diags/examples/WhereIntersection.java Sat Jan 26 19:24:46 2013 -0800
@@ -25,7 +25,7 @@
// key: compiler.misc.where.description.intersection
// key: compiler.misc.intersection.type
// key: compiler.err.prob.found.req
-// key: compiler.misc.inconvertible.types
+// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
// options: -XDdiags=where
// run: simple
--- a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.no.containerfor
-// key: compiler.err.invalid.container.wrong.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
- WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.wrong.containerfor
-// key: compiler.err.invalid.container.no.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/failover/CheckAttributedTree.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 6970584
+ * @bug 6970584 8006694
* @summary assorted position errors in compiler syntax trees
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../lib
* @build JavacTestingAbstractThreadedTest
- * @run main CheckAttributedTree -q -r -et ERRONEOUS .
+ * @run main/othervm CheckAttributedTree -q -r -et ERRONEOUS .
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
@@ -358,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;
@@ -391,7 +402,7 @@
}
}
- boolean checkFields(JCTree t) {
+ Field checkFields(JCTree t) {
List<Field> fieldsToCheck = treeUtil.getFieldsOfType(t,
excludedFields,
Symbol.class,
@@ -399,7 +410,7 @@
for (Field f : fieldsToCheck) {
try {
if (f.get(t) == null) {
- return false;
+ return f;
}
}
catch (IllegalAccessException e) {
@@ -407,7 +418,7 @@
//swallow it
}
}
- return true;
+ return null;
}
@Override
@@ -505,7 +516,7 @@
}
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
- out.println(diagnostic);
+ //out.println(diagnostic);
switch (diagnostic.getKind()) {
case ERROR:
errors++;
--- a/langtools/test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 7046778
+ * @bug 7046778 8006694
* @summary Project Coin: problem with diamond and member inner classes
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main DiamondAndInnerClassTest
+ * @run main/othervm DiamondAndInnerClassTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import com.sun.source.util.JavacTask;
import java.net.URI;
import java.util.Arrays;
--- a/langtools/test/tools/javac/generics/diamond/T6939780.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/T6939780.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,4 @@
+T6939780.java:18:33: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
T6939780.java:19:28: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
T6939780.java:20:28: compiler.warn.diamond.redundant.args.1: Foo<java.lang.Integer>, Foo<java.lang.Number>
-2 warnings
+3 warnings
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg05.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg05.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,25 +1,25 @@
Neg05.java:19:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:19:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>)
Neg05.java:20:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:20:45: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>)
Neg05.java:21:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:21:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>)
Neg05.java:22:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:22:43: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>)
Neg05.java:24:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:24:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>)
Neg05.java:25:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:25:45: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>)
Neg05.java:26:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:26:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>)
Neg05.java:27:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:27:43: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>)
Neg05.java:31:37: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:31:44: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<java.lang.String>))
Neg05.java:32:47: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:32:54: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<? extends java.lang.String>))
Neg05.java:33:32: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:33:39: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<?>))
Neg05.java:34:45: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:34:52: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<? super java.lang.String>))
Neg05.java:36:37: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:36:44: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<java.lang.String>))
Neg05.java:37:47: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:37:54: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<? extends java.lang.String>))
Neg05.java:38:32: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:38:39: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<?>))
Neg05.java:39:45: compiler.err.improperly.formed.type.inner.raw.param
+Neg05.java:39:52: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<? super java.lang.String>))
24 errors
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg10.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg10.java Sat Jan 26 19:24:46 2013 -0800
@@ -4,7 +4,8 @@
*
* @summary Check that 'complex' diamond can infer type that is too specific
* @author mcimadamore
- * @compile/fail/ref=Neg10.out Neg10.java -XDrawDiagnostics
+ * @compile/fail/ref=Neg10.out -source 7 -Xlint:-options Neg10.java -XDrawDiagnostics
+ * @compile Neg10.java -XDrawDiagnostics
*
*/
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg10.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg10.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-Neg10.java:16:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>)
+Neg10.java:17:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>)
1 error
--- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-T6315770.java:16:42: compiler.err.prob.found.req: (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer&java.lang.Runnable, java.lang.String)
+T6315770.java:16:42: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
+T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Integer,java.lang.Runnable)
2 errors
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String,java.lang.Object)
+T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: T, java.lang.Integer, java.lang.String,java.lang.Object)
1 error
--- a/langtools/test/tools/javac/generics/inference/6650759/T6650759m.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/inference/6650759/T6650759m.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-T6650759m.java:43:36: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
+T6650759m.java:43:36: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Integer,java.lang.Object)
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8006692/T8006692.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8006692
+ * @summary jdk/test/java/util/Collections/BigBinarySearch.java fails to compile
+ * @compile T8006692.java
+ */
+
+import java.util.*;
+
+class Test {
+ static void test(List<Integer> l, int i) {
+ equal(i, Collections.binarySearch(l, l.get(i)));
+ }
+ static void equal(Object x, Object y) {}
+}
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,14 +23,18 @@
/*
* @test
- * @bug 7062745
+ * @bug 7062745 8006694
* @summary Regression: difference in overload resolution when two methods
- * are maximally specific
+ * are maximally specific
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main GenericOverrideTest
+ * @run main/othervm GenericOverrideTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
--- a/langtools/test/tools/javac/lambda/BadConv03.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/BadConv03.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
+BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: BadConv03.B, (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
1 error
--- a/langtools/test/tools/javac/lambda/BadLambdaPos.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/BadLambdaPos.out Sat Jan 26 19:24:46 2013 -0800
@@ -4,6 +4,6 @@
BadLambdaPos.java:23:18: compiler.err.unexpected.lambda
BadLambdaPos.java:23:34: compiler.err.unexpected.lambda
BadLambdaPos.java:24:21: compiler.err.unexpected.lambda
-BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
8 errors
--- a/langtools/test/tools/javac/lambda/BadTargetType.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/BadTargetType.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
-BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
-BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
+BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary smoke test for functional interface annotation
+ * @compile/fail/ref=FunctionalInterfaceAnno.out -XDrawDiagnostics FunctionalInterfaceAnno.java
+ */
+class FunctionalInterfaceAnno {
+ @FunctionalInterface
+ static class A { } //not an interface
+
+ @FunctionalInterface
+ static abstract class B { } //not an interface
+
+ @FunctionalInterface
+ enum C { } //not an interface
+
+ @FunctionalInterface
+ @interface D { } //not an interface
+
+ @FunctionalInterface
+ interface E { } //no abstracts
+
+ @FunctionalInterface
+ interface F { default void m() { } } //no abstracts
+
+ @FunctionalInterface
+ interface G { String toString(); } //no abstracts
+
+ @FunctionalInterface
+ interface H { void m(); void n(); } //incompatible abstracts
+
+ @FunctionalInterface
+ interface I { void m(); } //ok
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,9 @@
+FunctionalInterfaceAnno.java:7:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.A)
+FunctionalInterfaceAnno.java:10:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.B)
+FunctionalInterfaceAnno.java:13:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.C)
+FunctionalInterfaceAnno.java:16:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.D)
+FunctionalInterfaceAnno.java:19:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.E, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.E))
+FunctionalInterfaceAnno.java:22:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.F, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.F))
+FunctionalInterfaceAnno.java:25:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.G, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.G))
+FunctionalInterfaceAnno.java:28:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.H, (compiler.misc.incompatible.abstracts: kindname.interface, FunctionalInterfaceAnno.H))
+8 errors
--- a/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,15 +23,19 @@
/**
* @test
- * @bug 8003280 8004102
+ * @bug 8003280 8004102 8006694
* @summary Add lambda tests
* perform several automated checks in lambda conversion, esp. around accessibility
+ * temporarily workaround combo tests are causing time out in several platforms
* @author Maurizio Cimadamore
* @library ../lib
* @build JavacTestingAbstractThreadedTest
- * @run main FunctionalInterfaceConversionTest
+ * @run main/othervm FunctionalInterfaceConversionTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
--- a/langtools/test/tools/javac/lambda/Intersection01.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/Intersection01.java Sat Jan 26 19:24:46 2013 -0800
@@ -25,7 +25,7 @@
* @test
* @bug 8002099
* @summary Add support for intersection types in cast expression
- * @compile/fail/ref=Intersection01.out -XDallowIntersectionTypes -XDrawDiagnostics Intersection01.java
+ * @compile/fail/ref=Intersection01.out -XDrawDiagnostics Intersection01.java
*/
class Intersection01 {
--- a/langtools/test/tools/javac/lambda/Intersection01.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/Intersection01.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
-Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
2 errors
--- a/langtools/test/tools/javac/lambda/LambdaConv09.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaConv09.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
-LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
-LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
-LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
-LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
+LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo1, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
+LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo2, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
+LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo3, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
+LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo5, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
4 errors
--- a/langtools/test/tools/javac/lambda/LambdaExpr10.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaExpr10.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,9 +1,9 @@
-LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr21.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,67 @@
+/*
+ * 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 8006684
+ * @summary Compiler produces java.lang.VerifyError: Bad type on operand stack
+ * @run main LambdaExpr21
+ */
+public class LambdaExpr21 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void foo();
+ }
+
+ static class Checker {
+ Checker(boolean cond) {
+ assertTrue(cond);
+ }
+ }
+
+ static {
+ SAM s = ()-> { new Checker(true) { }; };
+ s.foo();
+ }
+
+ static void test(){
+ SAM s = ()-> { new Checker(true) { }; };
+ s.foo();
+ }
+
+ static SAM s = ()-> { new Checker(true) { }; };
+
+ public static void main(String[] args) {
+ test();
+ s.foo();
+ assertTrue(assertionCount == 3);
+ }
+}
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,15 +23,18 @@
/*
* @test
- * @bug 7115050
- * @bug 8003280
+ * @bug 7115050 8003280 8005852 8006694
* @summary Add lambda tests
* Add parser support for lambda expressions
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../lib
* @build JavacTestingAbstractThreadedTest
- * @run main LambdaParserTest
+ * @run main/othervm LambdaParserTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
@@ -46,12 +49,12 @@
enum LambdaKind {
NILARY_EXPR("()->x"),
NILARY_STMT("()->{ return x; }"),
- ONEARY_SHORT_EXPR("x->x"),
- ONEARY_SHORT_STMT("x->{ return x; }"),
- ONEARY_EXPR("(#M1 #T1 x)->x"),
- ONEARY_STMT("(#M1 #T1 x)->{ return x; }"),
- TWOARY_EXPR("(#M1 #T1 x, #M2 #T2 y)->x"),
- TWOARY_STMT("(#M1 #T1 x, #M2 #T2 y)->{ return x; }");
+ ONEARY_SHORT_EXPR("#PN->x"),
+ ONEARY_SHORT_STMT("#PN->{ return x; }"),
+ ONEARY_EXPR("(#M1 #T1 #PN)->x"),
+ ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"),
+ TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"),
+ TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }");
String lambdaTemplate;
@@ -60,11 +63,12 @@
}
String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2,
- ModifierKind mk1, ModifierKind mk2) {
+ ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) {
return lambdaTemplate.replaceAll("#M1", mk1.modifier)
.replaceAll("#M2", mk2.modifier)
.replaceAll("#T1", pk1.parameterType)
- .replaceAll("#T2", pk2.parameterType);
+ .replaceAll("#T2", pk2.parameterType)
+ .replaceAll("#PN", pn.nameStr);
}
int arity() {
@@ -87,6 +91,17 @@
}
}
+ enum LambdaParameterName {
+ IDENT("x"),
+ UNDERSCORE("_");
+
+ String nameStr;
+
+ LambdaParameterName(String nameStr) {
+ this.nameStr = nameStr;
+ }
+ }
+
enum LambdaParameterKind {
IMPLICIT(""),
EXPLIICT_SIMPLE("A"),
@@ -151,8 +166,8 @@
}
String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2,
- ModifierKind mk1, ModifierKind mk2, LambdaKind lk, SubExprKind sk) {
- return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2))
+ ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) {
+ return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn))
.replaceAll("#S", sk.subExpression);
}
}
@@ -174,25 +189,27 @@
public static void main(String... args) throws Exception {
for (LambdaKind lk : LambdaKind.values()) {
- for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
- if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
- continue;
- for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
- if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
+ for (LambdaParameterName pn : LambdaParameterName.values()) {
+ for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
+ if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
continue;
- for (ModifierKind mk1 : ModifierKind.values()) {
- if (mk1 != ModifierKind.NONE && lk.isShort())
+ for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
+ if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
continue;
- if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
- continue;
- for (ModifierKind mk2 : ModifierKind.values()) {
- if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+ for (ModifierKind mk1 : ModifierKind.values()) {
+ if (mk1 != ModifierKind.NONE && lk.isShort())
+ continue;
+ if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
continue;
- for (SubExprKind sk : SubExprKind.values()) {
- for (ExprKind ek : ExprKind.values()) {
- pool.execute(
- new LambdaParserTest(pk1, pk2, mk1,
- mk2, lk, sk, ek));
+ for (ModifierKind mk2 : ModifierKind.values()) {
+ if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+ continue;
+ for (SubExprKind sk : SubExprKind.values()) {
+ for (ExprKind ek : ExprKind.values()) {
+ pool.execute(
+ new LambdaParserTest(pk1, pk2, mk1,
+ mk2, lk, sk, ek, pn));
+ }
}
}
}
@@ -209,6 +226,7 @@
ModifierKind mk1;
ModifierKind mk2;
LambdaKind lk;
+ LambdaParameterName pn;
SubExprKind sk;
ExprKind ek;
JavaSource source;
@@ -216,12 +234,13 @@
LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
- SubExprKind sk, ExprKind ek) {
+ SubExprKind sk, ExprKind ek, LambdaParameterName pn) {
this.pk1 = pk1;
this.pk2 = pk2;
this.mk1 = mk1;
this.mk2 = mk2;
this.lk = lk;
+ this.pn = pn;
this.sk = sk;
this.ek = ek;
this.source = new JavaSource();
@@ -239,7 +258,7 @@
public JavaSource() {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
source = template.replaceAll("#E",
- ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
+ ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk));
}
@Override
@@ -272,6 +291,9 @@
errorExpected = true;
}
+ errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
+ lk.arity() > 0;
+
if (errorExpected != diagChecker.errorFound) {
throw new Error("invalid diagnostics for source:\n" +
source.getCharContent(true) +
--- a/langtools/test/tools/javac/lambda/MethodReference04.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReference04.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
1 error
--- a/langtools/test/tools/javac/lambda/MethodReference25.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReference25.java Sat Jan 26 19:24:46 2013 -0800
@@ -25,21 +25,13 @@
* @test
* @bug 8003280
* @summary Add lambda tests
- * check that non-boxing method references conversion has the precedence
- * @run main MethodReference25
+ * check that non-boxing method references is not preferred over boxing one
+ * @compile/fail/ref=MethodReference25.out -XDrawDiagnostics MethodReference25.java
*/
-public class MethodReference25 {
+class MethodReference25 {
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
- static int assertionCount = 0;
-
- static void m(Integer i) { assertTrue(true); }
+ static void m(Integer i) { }
interface SAM1 {
void m(int x);
@@ -49,11 +41,10 @@
void m(Integer x);
}
- static void call(int i, SAM1 s) { s.m(i); assertTrue(false); }
+ static void call(int i, SAM1 s) { s.m(i); }
static void call(int i, SAM2 s) { s.m(i); }
public static void main(String[] args) {
- call(1, MethodReference25::m); //resolves to call(int, SAM2)
- assertTrue(assertionCount == 1);
+ call(1, MethodReference25::m); //ambiguous
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference25.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+MethodReference25.java:48:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference25.SAM1), MethodReference25, kindname.method, call(int,MethodReference25.SAM2), MethodReference25
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReference26.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReference26.java Sat Jan 26 19:24:46 2013 -0800
@@ -1,9 +1,30 @@
/*
- * @test /nodynamiccopyright/
- * @bug 8003280
- * @summary Add lambda tests
- * check strict method conversion does not allow loose method reference conversion
- * @compile/fail/ref=MethodReference26.out -XDrawDiagnostics MethodReference26.java
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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 check strict method conversion allows loose method reference conversion
+ * @compile MethodReference26.java
*/
class MethodReference26 {
@@ -18,6 +39,6 @@
static void call(Integer i, SAM s) { }
static void test() {
- call(1, MethodReference26::m); //ambiguous
+ call(1, MethodReference26::m); //ok
}
}
--- a/langtools/test/tools/javac/lambda/MethodReference26.out Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-MethodReference26.java:21:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference26.SAM), MethodReference26, kindname.method, call(java.lang.Integer,MethodReference26.SAM), MethodReference26
-1 error
--- a/langtools/test/tools/javac/lambda/MethodReference43.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReference43.java Sat Jan 26 19:24:46 2013 -0800
@@ -60,9 +60,9 @@
static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(true); }
+ static void m(SAM2 s) { assertTrue(false); }
static void m(SAM3 s) { assertTrue(false); }
- static void m(SAM4 s) { assertTrue(false); }
+ static void m(SAM4 s) { assertTrue(true); }
public static void main(String[] args) {
m(Foo::new);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference59.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004102
+ * @summary Add support for array constructor references
+ */
+public class MethodReference59 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface ArrayFactory<X> {
+ X make(int size);
+ }
+
+ public static void main(String[] args) {
+ ArrayFactory<int[]> factory1 = int[]::new;
+ int[] i1 = factory1.make(5);
+ assertTrue(i1.length == 5);
+ ArrayFactory<int[][]> factory2 = int[][]::new;
+ int[][] i2 = factory2.make(5);
+ assertTrue(i2.length == 5);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004102
+ * @summary Add support for array constructor references
+ * @compile/fail/ref=MethodReference60.out -XDrawDiagnostics MethodReference60.java
+ */
+public class MethodReference60 {
+
+ interface ArrayFactory<X> {
+ X make(int size);
+ }
+
+ interface BadArrayFactory1<X> {
+ X make();
+ }
+
+ interface BadArrayFactory2<X> {
+ X make(int i1, int i2);
+ }
+
+ interface BadArrayFactory3<X> {
+ X make(String s);
+ }
+
+ public static void main(String[] args) {
+ BadArrayFactory1<int[]> factory1 = int[]::new; //param mismatch
+ BadArrayFactory2<int[]> factory2 = int[]::new; //param mismatch
+ BadArrayFactory3<int[]> factory3 = int[]::new; //param mismatch
+ ArrayFactory<Integer> factory4 = int[]::new; //return type mismatch
+ ArrayFactory<Integer[]> factory5 = int[]::new; //return type mismatch
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,6 @@
+MethodReference60.java:49:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, compiler.misc.no.args, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:50:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, int,int, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:51:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, java.lang.String, kindname.class, Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int))))
+MethodReference60.java:52:42: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer))
+MethodReference60.java:53:44: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer[]))
+5 errors
--- a/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -24,14 +24,18 @@
/*
* @test
* @bug 7115052
- * @bug 8003280
+ * @bug 8003280 8006694
* @summary Add lambda tests
* Add parser support for method references
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../lib
* @build JavacTestingAbstractThreadedTest
- * @run main MethodReferenceParserTest
+ * @run main/othervm MethodReferenceParserTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
--- a/langtools/test/tools/javac/lambda/TargetType01.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType01.java Sat Jan 26 19:24:46 2013 -0800
@@ -27,7 +27,7 @@
* @summary Add lambda tests
* check nested case of overload resolution and lambda parameter inference
* @author Maurizio Cimadamore
- * @compile TargetType01.java
+ * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
*/
class TargetType01 {
@@ -43,7 +43,6 @@
static String M(F_S_S f){ return null; }
static {
- //ambiguity here - the compiler does not try all the combinations!
- M(x1 -> { return M( x2 -> { return x1 + x2; });});
+ M(x1 -> { return M( x2 -> { return x1 + x2; });}); //ambiguous
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType01.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,3 @@
+TargetType01.java:46:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+TargetType01.java:46:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType06.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType06.java Sat Jan 26 19:24:46 2013 -0800
@@ -4,7 +4,7 @@
* @summary Add lambda tests
* check complex case of target typing
* @author Maurizio Cimadamore
- * @compile/fail/ref=TargetType06.out -XDrawDiagnostics TargetType06.java
+ * @compile TargetType06.java
*/
import java.util.List;
--- a/langtools/test/tools/javac/lambda/TargetType06.out Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType06.java:25:23: compiler.err.cant.apply.symbol: kindname.method, map, TargetType06.Function<B,B>, @510, kindname.class, TargetType06, (compiler.misc.cyclic.inference: B)
-1 error
--- a/langtools/test/tools/javac/lambda/TargetType10.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType10.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-TargetType10.java:17:11: compiler.err.cant.apply.symbol: kindname.method, compose, TargetType10.Function<B,C>,TargetType10.Function<A,? extends B>, @500,@515, kindname.class, TargetType10.Test, (compiler.misc.cyclic.inference: B,A)
+TargetType10.java:17:18: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: B,A)
1 error
--- a/langtools/test/tools/javac/lambda/TargetType11.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType11.java Sat Jan 26 19:24:46 2013 -0800
@@ -4,7 +4,7 @@
* @summary Add lambda tests
* check that wildcards in the target method of a lambda conversion is handled correctly
* @author Maurizio Cimadamore
- * @compile/fail/ref=TargetType11.out -Xlint:unchecked -XDrawDiagnostics TargetType11.java
+ * @compile TargetType11.java
*/
class TargetType11 {
--- a/langtools/test/tools/javac/lambda/TargetType11.out Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-TargetType11.java:16:61: compiler.warn.unchecked.varargs.non.reifiable.type: TargetType11.Predicate<? super T>
-TargetType11.java:20:32: compiler.err.cant.apply.symbol: kindname.method, and, TargetType11.Predicate<? super T>[], @706,@718, kindname.class, TargetType11.Test, (compiler.misc.cyclic.inference: T)
-1 error
-1 warning
--- a/langtools/test/tools/javac/lambda/TargetType14.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType14.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType14.SAM<java.lang.String>, TargetType14.SAM<java.lang.Integer>)
+TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
1 error
--- a/langtools/test/tools/javac/lambda/TargetType17.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType17.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,9 +1,9 @@
-TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: byte)
+TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: short)
+TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: int)
+TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: long)
+TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: float)
+TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: double)
+TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: char)
+TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: boolean)
8 errors
--- a/langtools/test/tools/javac/lambda/TargetType21.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType21.java Sat Jan 26 19:24:46 2013 -0800
@@ -26,8 +26,8 @@
void test() {
call(x -> { throw new Exception(); }); //ambiguous
- call(x -> { System.out.println(""); }); //ok - resolves to call(SAM2)
- call(x -> { return (Object) null; }); //error - call(SAM3) is not applicable because of cyclic inference
- call(x -> { return null; }); ////ok - resolves to call(SAM1)
+ call(x -> { System.out.println(""); }); //ambiguous
+ call(x -> { return (Object) null; }); //cyclic inference
+ call(x -> { return null; }); //ambiguous
}
}
--- a/langtools/test/tools/javac/lambda/TargetType21.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType21.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,6 @@
-TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM2), TargetType21
-TargetType21.java:30:9: compiler.err.cant.apply.symbols: kindname.method, call, @737,{(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, <R,A>call(TargetType21.SAM3<R,A>), (compiler.misc.cyclic.inference: A))}
-2 errors
+TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:28:14: compiler.err.incompatible.thrown.types.in.lambda: java.lang.Exception
+TargetType21.java:29:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:30:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: A)
+TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+5 errors
--- a/langtools/test/tools/javac/lambda/TargetType26.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType26.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-TargetType26.java:16:7: compiler.err.cant.apply.symbol: kindname.method, call, Z, @340, kindname.class, TargetType26, (compiler.misc.cyclic.inference: Z)
+TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
1 error
--- a/langtools/test/tools/javac/lambda/TargetType27.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType27.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-TargetType27.java:18:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType27.F<A,R>, @490, kindname.class, TargetType27, (compiler.misc.cyclic.inference: R)
+TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: R)
1 error
--- a/langtools/test/tools/javac/lambda/TargetType28.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType28.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.String>)
-TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.Integer>)
+TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.String)
+TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.Integer)
2 errors
--- a/langtools/test/tools/javac/lambda/TargetType39.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType39.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-TargetType39.java:19:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @442, kindname.class, TargetType39, (compiler.misc.cyclic.inference: U)
-TargetType39.java:20:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @479, kindname.class, TargetType39, (compiler.misc.cyclic.inference: V)
+TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: U)
+TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: V)
2 errors
--- a/langtools/test/tools/javac/lambda/TargetType43.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType43.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
-TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
-TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
4 errors
--- a/langtools/test/tools/javac/lambda/TargetType45.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType45.java Sat Jan 26 19:24:46 2013 -0800
@@ -3,7 +3,7 @@
* @bug 8003280
* @summary Add lambda tests
* compiler crashes during flow analysis as it fails to report diagnostics during attribution
- * @compile/fail/ref=TargetType45.out -XDrawDiagnostics TargetType45.java
+ * @compile TargetType45.java
*/
class TargetType45 {
--- a/langtools/test/tools/javac/lambda/TargetType45.out Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType45.java:27:28: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.inconvertible.types: TargetType45.Mapper<java.lang.String,java.lang.Integer>, TargetType45.Mapper<? super java.lang.Object,? extends java.lang.Integer>))
-1 error
--- a/langtools/test/tools/javac/lambda/TargetType50.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType50.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,3 +1,3 @@
-TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
-TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
+TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
+TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType51.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary smoke test for combinator-like stuck analysis
+ * @author Maurizio Cimadamore
+ * @compile TargetType51.java
+ */
+
+import java.util.Comparator;
+
+class TargetType51 {
+
+ interface SimpleMapper<T, U> {
+ T map(U t);
+ }
+
+ interface SimpleList<X> {
+ SimpleList<X> sort(Comparator<? super X> c);
+ }
+
+ static class Person {
+ String getName() { return ""; }
+ }
+
+ <T, U extends Comparable<? super U>> Comparator<T> comparing(SimpleMapper<U, T> mapper) { return null; }
+
+ static class F<U extends Comparable<? super U>, T> {
+ F(SimpleMapper<U, T> f) { }
+ }
+
+ void testAssignmentContext(SimpleList<Person> list, boolean cond) {
+ SimpleList<Person> p1 = list.sort(comparing(Person::getName));
+ SimpleList<Person> p2 = list.sort(comparing(x->x.getName()));
+ SimpleList<Person> p3 = list.sort(cond ? comparing(Person::getName) : comparing(x->x.getName()));
+ SimpleList<Person> p4 = list.sort((cond ? comparing(Person::getName) : comparing(x->x.getName())));
+ }
+
+ void testMethodContext(SimpleList<Person> list, boolean cond) {
+ testMethodContext(list.sort(comparing(Person::getName)), true);
+ testMethodContext(list.sort(comparing(x->x.getName())), true);
+ testMethodContext(list.sort(cond ? comparing(Person::getName) : comparing(x->x.getName())), true);
+ testMethodContext(list.sort((cond ? comparing(Person::getName) : comparing(x->x.getName()))), true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType52.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary uncatched sam conversion failure exception lead to javac crash
+ * @compile/fail/ref=TargetType52.out -XDrawDiagnostics TargetType52.java
+ */
+class TargetType52 {
+
+ interface FI<T extends CharSequence, V extends java.util.AbstractList<T>> {
+ T m(V p);
+ }
+
+ void m(FI<? extends CharSequence, ? extends java.util.ArrayList<? extends CharSequence>> fip) { }
+
+ void test() {
+ m(p -> p.get(0));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType52.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+TargetType52.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @444, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
+1 error
--- a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Sat Jan 26 19:24:46 2013 -0800
@@ -24,15 +24,18 @@
/*
* @test
* @bug 7194586
- *
- * @bug 8003280
+ * @bug 8003280 8006694
* @summary Add lambda tests
* Add back-end support for invokedynamic
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../lib
* @build JavacTestingAbstractThreadedTest
- * @run main TestInvokeDynamic
+ * @run main/othervm TestInvokeDynamic
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.TaskEvent;
@@ -48,7 +51,6 @@
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symtab;
@@ -67,11 +69,8 @@
import java.util.Locale;
import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
import static com.sun.tools.javac.jvm.ClassFile.*;
--- a/langtools/test/tools/javac/lambda/VoidCompatibility.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/VoidCompatibility.java Sat Jan 26 19:24:46 2013 -0800
@@ -3,7 +3,7 @@
* @bug 8003280
* @summary Add lambda tests
* check that that void compatibility affects overloading as expected
- * @compile/fail/ref=VoidCompatibility.out -XDrawDiagnostics VoidCompatibility.java
+ * @compile VoidCompatibility.java
*/
class VoidCompatibility {
@@ -14,13 +14,13 @@
void schedule(Thunk<?> t) { }
void test() {
- schedule(() -> System.setProperty("done", "true")); //2
+ schedule(() -> System.setProperty("done", "true")); //non-void most specific
schedule(() -> { System.setProperty("done", "true"); }); //1
schedule(() -> { return System.setProperty("done", "true"); }); //2
schedule(() -> System.out.println("done")); //1
schedule(() -> { System.out.println("done"); }); //1
schedule(Thread::yield); //1
- schedule(Thread::getAllStackTraces); //ambiguous
+ schedule(Thread::getAllStackTraces); //non-void most specific
schedule(Thread::interrupted); //1 (most specific)
}
}
--- a/langtools/test/tools/javac/lambda/VoidCompatibility.out Thu Jan 24 16:49:37 2013 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-VoidCompatibility.java:17:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
-VoidCompatibility.java:23:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
-2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Check usages of underscore as identifier generate warnings
+ * @compile/fail/ref=WarnUnderscoreAsIdent.out -XDrawDiagnostics -Werror WarnUnderscoreAsIdent.java
+ */
+package _._;
+
+import _._;
+
+class _ {
+ String _ = null;
+ void _(String _) { }
+ void testLocal() {
+ String _ = null;
+ }
+ void testFor() {
+ for (int _ = 0; _ < 10; _++);
+ }
+ void testTry() {
+ try { } catch (Throwable _) { }
+ }
+ void testLabel() {
+ _:
+ for (;;) {
+ break _;
+ }
+ _:
+ for (;;) {
+ continue _;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.out Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,20 @@
+WarnUnderscoreAsIdent.java:29:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:29:11: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:8: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:33:7: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:34:12: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:37:16: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:18: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:25: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:33: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:43:34: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:46:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:48:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:50:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:52:22: compiler.warn.underscore.as.identifier
+- compiler.err.warnings.and.werror
+1 error
+17 warnings
--- a/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
+LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: QooRoo, (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, Planet))
+NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: Planet, (compiler.misc.no.abstracts: kindname.interface, Planet))
1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,9 +1,9 @@
-NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
8 errors
--- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -248,7 +248,7 @@
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
- Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
+ null, null, Arrays.asList(source));
try {
ct.analyze();
} catch (Throwable ex) {
--- a/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: AbstractClass_neg.SAM)
1 error
--- a/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
1 error
--- a/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -149,8 +149,7 @@
return false; //ambiguous target type
}
else if(lambdaBody == LambdaBody.IMPLICIT) {
- if(returnValue != ReturnValue.INTEGER) //ambiguous target type
- return false;
+ return false;
}
else { //explicit parameter type
if(fInterface.getParameterType().equals("Integer")) //ambiguous target type
--- a/langtools/test/tools/javac/lambda/methodReference/SamConversion.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/methodReference/SamConversion.java Sat Jan 26 19:24:46 2013 -0800
@@ -149,14 +149,6 @@
test2(A::method3, 4);
test2(new A()::method4, 5);
test2(new A()::method5, 6);
- A a = new A(A::method1); //A(Foo f) called
- assertTrue(a.method2(1) == 11);
- assertTrue(a.method4(1) == 11);
- assertTrue(a.method5(1) == 11);
- A a2 = new A(new A()::method2); //A(Bar b) called
- assertTrue(a2.method2(1) == 12);
- assertTrue(a2.method4(1) == 12);
- assertTrue(a2.method5(1) == 12);
}
/**
@@ -279,7 +271,7 @@
testConditionalExpression(false);
testLambdaExpressionBody();
- assertTrue(assertionCount == 38);
+ assertTrue(assertionCount == 32);
}
static class MyException extends Exception {}
--- a/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -186,10 +186,7 @@
if(context != Context.CONSTRUCTOR && fInterface != FInterface.C && methodDef == MethodDef.METHOD6)
//method that throws exceptions not thrown by the interface method is a mismatch
return false;
- if(context == Context.CONSTRUCTOR &&
- methodReference != MethodReference.METHOD1 &&
- methodReference != MethodReference.METHOD2 &&
- methodReference != MethodReference.METHOD3)//ambiguous reference
+ if(context == Context.CONSTRUCTOR)
return false;
return true;
}
--- a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,14 +23,18 @@
/*
* @test
- * @bug 8003280
+ * @bug 8003280 8006694
* @summary Add lambda tests
* Automatic test for checking correctness of structural most specific test routine
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main/timeout=600 StructuralMostSpecificTest
+ * @run main/othervm/timeout=600 StructuralMostSpecificTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out Sat Jan 26 19:24:46 2013 -0800
@@ -1,2 +1,2 @@
-InferenceTest_neg5.java:14:13: compiler.err.cant.apply.symbol: kindname.method, method1, InferenceTest_neg5.SAM1<X>, @419, kindname.class, InferenceTest_neg5, (compiler.misc.cyclic.inference: X)
+InferenceTest_neg5.java:14:21: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: X)
1 error
--- a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,16 +23,20 @@
/**
* @test
- * @bug 8003280
+ * @bug 8003280 8006694
* @summary Add lambda tests
* perform automated checks in type inference in lambda expressions
* in different contexts
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../../lib
* @build JavacTestingAbstractThreadedTest
* @compile TypeInferenceComboTest.java
- * @run main/timeout=360 TypeInferenceComboTest
+ * @run main/othervm/timeout=360 TypeInferenceComboTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
@@ -256,16 +260,6 @@
};
public void run() {
- outWriter.println("kk:");
- StringBuilder sb = new StringBuilder("SamKind:");
- sb.append(samKind).append(" SamTargetType:")
- .append(samTargetType).append(" ParameterType:").append(parameterType)
- .append(" ReturnType:").append(returnType).append(" Context:")
- .append(context).append(" LambdaKind:").append(lambdaKind)
- .append(" LambdaBodyType:").append(lambdaBodyType)
- .append(" ParameterKind:").append(parameterKind).append(" Keyword:")
- .append(keyword);
- outWriter.println(sb);
DiagnosticChecker dc = new DiagnosticChecker();
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), dc,
null, null, Arrays.asList(samSourceFile, clientSourceFile));
--- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -807,20 +807,8 @@
fail("Could not load class", e);
}
}
-
- public void testSynchronizedDefault() {
- try {
- java.lang.Class.forName("org.openjdk.tests.vm.SynchronizedDefault");
- } catch (Exception e) {
- fail("Could not load class", e);
- }
- }
}
interface StrictfpDefault {
default strictfp void m() {}
}
-
-interface SynchronizedDefault {
- default synchronized void m() {}
-}
--- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/FDSeparateCompilationTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/FDSeparateCompilationTest.java Sat Jan 26 19:24:46 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
@@ -23,6 +23,9 @@
* questions.
*/
+// this test has been disabled because of timeout issues.
+// see JDK-8006746
+
package org.openjdk.tests.vm;
import java.util.*;
@@ -91,7 +94,7 @@
private static final ConcreteMethod canonicalMethod = new ConcreteMethod(
"String", "m", "returns " + EMPTY + ";", AccessFlag.PUBLIC);
- @Test(groups = "vm", dataProvider = "allShapes")
+ @Test(enabled = false, groups = "vm", dataProvider = "allShapes")
public void separateCompilationTest(Hierarchy hs) {
ClassCase cc = hs.root;
Type type = sourceTypeFrom(hs.root);
--- a/langtools/test/tools/javac/lib/JavacTestingAbstractThreadedTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/lib/JavacTestingAbstractThreadedTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -26,6 +26,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
@@ -67,9 +68,7 @@
protected static void checkAfterExec(boolean printCheckCount)
throws InterruptedException {
pool.shutdown();
- while (!pool.isTerminated()) {
- Thread.sleep(10);
- }
+ pool.awaitTermination(15, TimeUnit.MINUTES);
if (errCount.get() > 0) {
if (throwAssertionOnError) {
closePrinters();
--- a/langtools/test/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 7030606
+ * @bug 7030606 8006694
* @summary Project-coin: multi-catch types should be pairwise disjoint
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main DisjunctiveTypeWellFormednessTest
+ * @run main/othervm DisjunctiveTypeWellFormednessTest
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
--- a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out Sat Jan 26 19:24:46 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
--- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Sat Jan 26 19:24:46 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<String> names = new ArrayList<String>();
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.");
}
}
--- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Sat Jan 26 19:24:46 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.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Sat Jan 26 19:24:46 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!<tvar T>
+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!<tvar T>
+check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A!<tvar T>
+check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List<!:empty clss X!>
\ No newline at end of file
--- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Sat Jan 26 19:24:46 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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,2 @@
+C1.java:24:18: compiler.err.cant.resolve: kindname.class, Bogus, ,
+1 error
--- a/langtools/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,44 +23,44 @@
@TraceResolve(keys={"compiler.err.ref.ambiguous"})
class PrimitiveOverReferenceVarargsAmbiguous {
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_byte(byte... b) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_byte(Byte... b) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_short(short... s) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_short(Short... s) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_int(int... i) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_int(Integer... i) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_long(long... l) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_long(Long... l) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_float(float... f) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_float(Float... f) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_double(double... d) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_double(Double... d) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_char(char... c) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_char(Character... c) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
static void m_bool(boolean... z) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+ @Candidate(applicable=Phase.VARARGS)
static void m_bool(Boolean... z) {}
{
--- a/langtools/test/tools/javac/tree/TreeKindTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/tree/TreeKindTest.java Sat Jan 26 19:24:46 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;
--- a/langtools/test/tools/javac/tree/TreePosTest.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/tree/TreePosTest.java Sat Jan 26 19:24:46 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]+", " ");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/treeannotests/AnnoTreeTests.java Sat Jan 26 19:24:46 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)
+}
--- a/langtools/test/tools/javac/treeannotests/TestProcessor.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/treeannotests/TestProcessor.java Sat Jan 26 19:24:46 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 <i>name</i>=<i>value</i>.
*/
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());
}
--- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java Thu Jan 24 16:49:37 2013 -0800
+++ /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<T extends @A Object> extends @B LinkedList<T> implements @C List<T> {
-
- 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<? extends @A String> 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) {
-
- }
-}
--- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out Thu Jan 24 16:49:37 2013 -0800
+++ /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
--- a/langtools/test/tools/javac/varargs/7042566/T7042566.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/varargs/7042566/T7042566.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,17 @@
/*
* @test
- * @bug 7042566
+ * @bug 7042566 8006694
* @summary Unambiguous varargs method calls flagged as ambiguous
+ * temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main T7042566
+ * @run main/othervm T7042566
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.io.File;
import java.net.URI;
import java.util.Arrays;
--- a/langtools/test/tools/javac/varargs/warning/Warn4.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/varargs/warning/Warn4.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,14 +23,18 @@
/**
* @test
- * @bug 6945418 6993978
+ * @bug 6945418 6993978 8006694
* @summary Project Coin: Simplified Varargs Method Invocation
+ * temporarily workaround combo tests are causing time out in several platforms
* @author mcimadamore
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main Warn4
+ * @run main/othervm Warn4
*/
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import java.util.Set;
@@ -238,7 +242,6 @@
for (Warning wkind : Warning.values()) {
boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
suppressLevelClient, suppressLevelDecl, modKind);
- System.out.println("SUPPRESSED = " + isSuppressed);
badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) !=
diagChecker.warnings.contains(wkind);
}
--- a/langtools/test/tools/javac/varargs/warning/Warn5.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javac/varargs/warning/Warn5.java Sat Jan 26 19:24:46 2013 -0800
@@ -23,13 +23,18 @@
/**
* @test
- * @bug 6993978 7097436
+ * @bug 6993978 7097436 8006694
* @summary Project Coin: Annotation to reduce varargs warnings
+ * temporarily workaround combo tests are causing time out in several platforms
* @author mcimadamore
* @library ../../lib
* @build JavacTestingAbstractThreadedTest
- * @run main Warn5
+ * @run main/othervm Warn5
*/
+
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
import java.net.URI;
import java.util.Arrays;
import java.util.EnumSet;
--- a/langtools/test/tools/javadoc/6958836/Test.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javadoc/6958836/Test.java Sat Jan 26 19:24:46 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
@@ -61,6 +61,7 @@
// Force en_US locale in lieu of something like -XDrawDiagnostics.
// For some reason, this must be the first option when used.
opts.addAll(list("-locale", "en_US"));
+ opts.add("-Xdoclint:none");
opts.addAll(list("-classpath", System.getProperty("test.src")));
opts.addAll(list("-d", testOutDir.getPath()));
opts.addAll(testOpts);
--- a/langtools/test/tools/javadoc/6964914/Test.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javadoc/6964914/Test.java Sat Jan 26 19:24:46 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
@@ -45,6 +45,7 @@
void javadoc(String path, String expect) {
File testSrc = new File(System.getProperty("test.src"));
String[] args = {
+ "-Xdoclint:none",
"-source", "1.4", // enables certain Parser warnings
"-bootclasspath", System.getProperty("sun.boot.class.path"),
"-classpath", ".",
--- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Sat Jan 26 19:24:46 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
@@ -57,6 +57,7 @@
Process p = new ProcessBuilder()
.command(javadoc.getPath(),
"-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"),
+ "-Xdoclint:none",
"-package",
new File(testSrc, thisClassName + ".java").getPath())
.redirectErrorStream(true)
--- a/langtools/test/tools/javadoc/MaxWarns.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javadoc/MaxWarns.java Sat Jan 26 19:24:46 2013 -0800
@@ -74,7 +74,7 @@
String javadoc(File f) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- String[] args = { "-d", "api", f.getPath() };
+ String[] args = { "-Xdoclint:none", "-d", "api", f.getPath() };
int rc = com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
com.sun.tools.doclets.standard.Standard.class.getName(), args);
pw.flush();
--- a/langtools/test/tools/javadoc/T6551367.java Thu Jan 24 16:49:37 2013 -0800
+++ b/langtools/test/tools/javadoc/T6551367.java Sat Jan 26 19:24:46 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
@@ -46,7 +46,7 @@
File source = new File(testSrc, file);
int rc = execute("javadoc", "T6551367",
T6551367.class.getClassLoader(),
- new String[]{source.getPath(), "-d", destDir.getAbsolutePath()});
+ new String[]{"-Xdoclint:none", source.getPath(), "-d", destDir.getAbsolutePath()});
if (rc != 0)
throw new Error("unexpected exit from javadoc: " + rc);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,251 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8004834
+ * @summary Add doclint support into javadoc
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.tools.Diagnostic;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import static javax.tools.Diagnostic.Kind.*;
+
+import com.sun.tools.javac.main.Main;
+
+public class DocLintTest {
+ public static void main(String... args) throws Exception {
+ new DocLintTest().run();
+ }
+
+ DocumentationTool javadoc;
+ StandardJavaFileManager fm;
+ JavaFileObject file;
+
+ final String code =
+ /* 01 */ "/** Class comment. */\n" +
+ /* 02 */ "public class Test {\n" +
+ /* 03 */ " /** Method comment. */\n" +
+ /* 04 */ " public void method() { }\n" +
+ /* 05 */ "\n" +
+ /* 06 */ " /** Syntax < error. */\n" +
+ /* 07 */ " private void syntaxError() { }\n" +
+ /* 08 */ "\n" +
+ /* 09 */ " /** @see DoesNotExist */\n" +
+ /* 10 */ " protected void referenceError() { }\n" +
+ /* 11 */ "\n" +
+ /* 12 */ " /** @return */\n" +
+ /* 13 */ " public int emptyReturn() { return 0; }\n" +
+ /* 14 */ "}\n";
+
+ private final String rawDiags = "-XDrawDiagnostics";
+
+ private enum Message {
+ // doclint messages
+ DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"),
+ DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"),
+ DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"),
+
+ // doclint messages when -XDrawDiagnostics is not in effect
+ DL_ERR9A(ERROR, "Test.java:9: error: reference not found"),
+ DL_WRN12A(WARNING, "Test.java:12: warning: no description for @return"),
+
+ // javadoc messages about bad content: these should only appear when doclint is disabled
+ JD_WRN10(WARNING, "Test.java:10: warning - Tag @see: reference not found: DoesNotExist"),
+ JD_WRN13(WARNING, "Test.java:13: warning - @return tag has no arguments."),
+
+ // javadoc messages for bad options
+ OPT_BADARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint option"),
+ OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments");
+
+ final Diagnostic.Kind kind;
+ final String text;
+
+ static Message get(String text) {
+ for (Message m: values()) {
+ if (m.text.equals(text))
+ return m;
+ }
+ return null;
+ }
+
+ Message(Diagnostic.Kind kind, String text) {
+ this.kind = kind;
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + kind + ",\"" + text + "\"]";
+ }
+ }
+
+ void run() throws Exception {
+ javadoc = ToolProvider.getSystemDocumentationTool();
+ fm = javadoc.getStandardFileManager(null, null, null);
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
+ file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncoding) {
+ return code;
+ }
+ };
+
+ test(Collections.<String>emptyList(),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A));
+
+ test(Arrays.asList(rawDiags),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+ test(Arrays.asList("-Xdoclint:none"),
+ Main.Result.OK,
+ EnumSet.of(Message.JD_WRN10, Message.JD_WRN13));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:all/public"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.OPT_BADQUAL));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"),
+ Main.Result.OK,
+ EnumSet.of(Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:syntax"),
+ Main.Result.OK,
+ EnumSet.of(Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR6, Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:reference"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:badarg"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.OPT_BADARG));
+
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ void test(List<String> opts, Main.Result expectResult, Set<Message> expectMessages) {
+ System.err.println("test: " + opts);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ List<JavaFileObject> files = Arrays.asList(file);
+ try {
+ DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files);
+ boolean ok = t.call();
+ pw.close();
+ String out = sw.toString().replaceAll("[\r\n]+", "\n");
+ if (!out.isEmpty())
+ System.err.println(out);
+ if (ok && expectResult != Main.Result.OK) {
+ error("Compilation succeeded unexpectedly");
+ } else if (!ok && expectResult != Main.Result.ERROR) {
+ error("Compilation failed unexpectedly");
+ } else
+ check(out, expectMessages);
+ } catch (IllegalArgumentException e) {
+ System.err.println(e);
+ String expectOut = expectMessages.iterator().next().text;
+ if (expectResult != Main.Result.CMDERR)
+ error("unexpected exception caught");
+ else if (!e.getMessage().equals(expectOut)) {
+ error("unexpected exception message: "
+ + e.getMessage()
+ + " expected: " + expectOut);
+ }
+ }
+
+// if (errors > 0)
+// throw new Error("stop");
+ }
+
+ private void check(String out, Set<Message> expect) {
+ Pattern ignore = Pattern.compile("^(Building|Constructing|Generating|Loading|Standard|Starting| ) .*");
+ Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)");
+ Set<Message> found = EnumSet.noneOf(Message.class);
+ int e = 0, w = 0;
+ for (String line: out.split("[\r\n]+")) {
+ if (ignore.matcher(line).matches())
+ continue;
+
+ Matcher s = stats.matcher(line);
+ if (s.matches()) {
+ int i = Integer.valueOf(s.group(1));
+ if (s.group(2).equals("error"))
+ e++;
+ else
+ w++;
+ continue;
+ }
+
+ Message m = Message.get(line);
+ if (m == null)
+ error("Unexpected line: " + line);
+ else
+ found.add(m);
+ }
+ for (Message m: expect) {
+ if (!found.contains(m))
+ error("expected message not found: " + m.text);
+ }
+ for (Message m: found) {
+ if (!expect.contains(m))
+ error("unexpected message found: " + m.text);
+ }
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/NewArray.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/Presence.java Sat Jan 26 19:24:46 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<T> this, List<@A String> @A [] param1, String @A [] @A ... param2)");
+ out.println(" throws @A Exception {");
+ out.println(" @A String lc1 = null;");
+ out.println(" @A List<@A String> lc2 = null;");
+ out.println(" @A String @A [] [] @A[] lc3 = null;");
+ out.println(" List<? extends @A List<@A String>> 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/PresenceInner.java Sat Jan 26 19:24:46 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<T extends @A Object> { }");
+ 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/T6855990.java Sat Jan 26 19:24:46 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 { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/Visibility.java Sat Jan 26 19:24:46 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/typeAnnotations/Wildcards.java Sat Jan 26 19:24:46 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<? extends @A Number> f;");
+
+ out.println(" List<? extends @A Object> test(List<? extends @A Number> p) {");
+ out.println(" List<? extends @A Object> 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SJavac.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,573 @@
+/*
+ * 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.util.*;
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.charset.*;
+
+import com.sun.tools.sjavac.Main;
+
+public
+class SJavac {
+
+ public static void main(String... args) throws Exception {
+ SJavac s = new SJavac();
+ s.test();
+ }
+
+ FileSystem defaultfs = FileSystems.getDefault();
+
+ // Where to put generated sources that will
+ // test aspects of sjavac, ie JTWork/scratch/gensrc
+ Path gensrc;
+ // More gensrc dirs are used to test merging of serveral source roots.
+ Path gensrc2;
+ Path gensrc3;
+
+ // Where to put compiled classes.
+ Path bin;
+ // Where to put c-header files.
+ Path headers;
+
+ // The sjavac compiler.
+ Main main = new Main();
+
+ // Remember the previous bin and headers state here.
+ Map<String,Long> previous_bin_state;
+ Map<String,Long> previous_headers_state;
+
+ public void test() throws Exception {
+ gensrc = defaultfs.getPath("gensrc");
+ gensrc2 = defaultfs.getPath("gensrc2");
+ gensrc3 = defaultfs.getPath("gensrc3");
+ bin = defaultfs.getPath("bin");
+ headers = defaultfs.getPath("headers");
+
+ Files.createDirectory(gensrc);
+ Files.createDirectory(gensrc2);
+ Files.createDirectory(gensrc3);
+ Files.createDirectory(bin);
+ Files.createDirectory(headers);
+
+ initialCompile();
+ incrementalCompileNoChanges();
+ incrementalCompileDroppingClasses();
+ incrementalCompileWithChange();
+ incrementalCompileDropAllNatives();
+ incrementalCompileAddNative();
+ incrementalCompileChangeNative();
+ compileWithOverrideSource();
+ compileWithInvisibleSources();
+ compileCircularSources();
+
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ }
+
+ void initialCompile() throws Exception {
+ System.out.println("\nInitial compile of gensrc.");
+ System.out.println("----------------------------");
+ populate(gensrc,
+ "alfa/AINT.java",
+ "package alfa; public interface AINT { void aint(); }",
+
+ "alfa/A.java",
+ "package alfa; public class A implements AINT { "+
+ "public final static int DEFINITION = 17; public void aint() { } }",
+
+ "alfa/AA.java",
+ "package alfa;"+
+ "// A package private class, not contributing to the public api.\n"+
+ "class AA {"+
+ " // A properly nested static inner class.\n"+
+ " static class AAA { }\n"+
+ " // A properly nested inner class.\n"+
+ " class AAAA { }\n"+
+ " Runnable foo() {\n"+
+ " // A proper anonymous class.\n"+
+ " return new Runnable() { public void run() { } };\n"+
+ " }\n"+
+ " AAA aaa;\n"+
+ " AAAA aaaa;\n"+
+ " AAAAA aaaaa;\n"+
+ "}\n"+
+ "class AAAAA {\n"+
+ " // A bad auxiliary class, but no one is referencing it\n"+
+ " // from outside of this source file, therefore it is ok.\n"+
+ "}\n",
+
+ "beta/BINT.java",
+ "package beta;public interface BINT { void foo(); }",
+
+ "beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } native void foo(); }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ previous_bin_state = collectState(bin);
+ previous_headers_state = collectState(headers);
+ }
+
+ void incrementalCompileNoChanges() throws Exception {
+ System.out.println("\nTesting that no change in sources implies no change in binaries.");
+ System.out.println("------------------------------------------------------------------");
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyEqual(new_bin_state, previous_bin_state);
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(previous_headers_state, new_headers_state);
+ }
+
+ void incrementalCompileDroppingClasses() throws Exception {
+ System.out.println("\nTesting that deleting AA.java deletes all");
+ System.out.println("generated inner class as well as AA.class");
+ System.out.println("-----------------------------------------");
+ removeFrom(gensrc, "alfa/AA.java");
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
+ "bin/alfa/AA$1.class",
+ "bin/alfa/AA$AAAA.class",
+ "bin/alfa/AA$AAA.class",
+ "bin/alfa/AAAAA.class",
+ "bin/alfa/AA.class");
+
+ previous_bin_state = new_bin_state;
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(previous_headers_state, new_headers_state);
+ }
+
+ void incrementalCompileWithChange() throws Exception {
+ System.out.println("\nNow update the A.java file with a new timestamps and");
+ System.out.println("new final static definition. This should trigger a recompile,");
+ System.out.println("not only of alfa, but also beta.");
+ System.out.println("But check that the generated native header was not updated!");
+ System.out.println("Since we did not modify the native api of B.");
+ System.out.println("-------------------------------------------------------------");
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; public class A implements AINT { "+
+ "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/alfa/AINT.class",
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(new_headers_state, previous_headers_state);
+ }
+
+ void incrementalCompileDropAllNatives() throws Exception {
+ System.out.println("\nNow update the B.java file with one less native method,");
+ System.out.println("ie it has no longer any methods!");
+ System.out.println("Verify that beta_B.h is removed!");
+ System.out.println("---------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void incrementalCompileAddNative() throws Exception {
+ System.out.println("\nNow update the B.java file with a final static annotated with @Native.");
+ System.out.println("Verify that beta_B.h is added again!");
+ System.out.println("------------------------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } "+
+ "@java.lang.annotation.Native final static int alfa = 42; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void incrementalCompileChangeNative() throws Exception {
+ System.out.println("\nNow update the B.java file with a new value for the final static"+
+ " annotated with @Native.");
+ System.out.println("Verify that beta_B.h is rewritten again!");
+ System.out.println("-------------------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } "+
+ "@java.lang.annotation.Native final static int alfa = 43; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyNewerFiles(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void compileWithOverrideSource() throws Exception {
+ System.out.println("\nNow verify that we can override sources to be compiled.");
+ System.out.println("Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,");
+ System.out.println("only compile ok beta.B in gensrc2.");
+ System.out.println("---------------------------------------------------------------------------");
+
+ delete(gensrc);
+ delete(gensrc2);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }",
+ "beta/B.java",
+ "package beta; public class B { broken",
+ "gamma/C.java",
+ "package gamma; public class C { }");
+
+ populate(gensrc2,
+ "beta/B.java",
+ "package beta; public class B { }");
+
+ compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/beta/B.class",
+ "bin/gamma/C.class",
+ "bin/javac_state");
+
+ System.out.println("----- Compile with exluded beta went well!");
+ delete(bin);
+ compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+ delete(bin);
+ }
+
+ void compileWithInvisibleSources() throws Exception {
+ System.out.println("\nNow verify that we can make sources invisible to linking (sourcepath).");
+ System.out.println("Compile gensrc and link against gensrc2 and gensrc3, however");
+ System.out.println("gensrc2 contains broken code in beta.B, thus we must exclude that package");
+ System.out.println("fortunately gensrc3 contains a proper beta.B.");
+ System.out.println("------------------------------------------------------------------------");
+
+ // Start with a fresh gensrcs and bin.
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }");
+ populate(gensrc2,"beta/B.java",
+ "package beta; public class B { broken",
+ "gamma/C.java",
+ "package gamma; public class C { }");
+ populate(gensrc3, "beta/B.java",
+ "package beta; public class B { }");
+
+ compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
+ "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("The first compile went well!");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/javac_state");
+
+ System.out.println("----- Compile with exluded beta went well!");
+ delete(bin);
+ compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
+ "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+ delete(bin);
+ }
+
+ void compileCircularSources() throws Exception {
+ System.out.println("\nNow verify that circular sources split on multiple cores can be compiled.");
+ System.out.println("---------------------------------------------------------------------------");
+
+ // Start with a fresh gensrcs and bin.
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; public class A { beta.B b; }",
+ "beta/B.java",
+ "package beta; public class B { gamma.C c; }",
+ "gamma/C.java",
+ "package gamma; public class C { alfa.A a; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
+ "--server:portfile=testserver,background=false","--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/beta/B.class",
+ "bin/gamma/C.class",
+ "bin/javac_state");
+ delete(bin);
+ }
+
+ void removeFrom(Path dir, String... args) throws IOException {
+ for (String filename : args) {
+ Path p = dir.resolve(filename);
+ Files.delete(p);
+ }
+ }
+
+ void populate(Path src, String... args) throws IOException {
+ if (!Files.exists(src)) {
+ Files.createDirectory(src);
+ }
+ String[] a = args;
+ for (int i = 0; i<a.length; i+=2) {
+ String filename = a[i];
+ String content = a[i+1];
+ Path p = src.resolve(filename);
+ Files.createDirectories(p.getParent());
+ PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
+ Charset.defaultCharset()));
+ out.println(content);
+ out.close();
+ }
+ }
+
+ void delete(Path root) throws IOException {
+ if (!Files.exists(root)) return;
+ Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException
+ {
+ if (e == null) {
+ if (!dir.equals(root)) Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ } else {
+ // directory iteration failed
+ throw e;
+ }
+ }
+ });
+ }
+
+ void compile(String... args) throws Exception {
+ int rc = main.go(args, System.out, System.err);
+ if (rc != 0) throw new Exception("Error during compile!");
+
+ // Wait a second, to get around the (temporary) problem with
+ // second resolution in the Java file api. But do not do this
+ // on windows where the timestamps work.
+ long in_a_sec = System.currentTimeMillis()+1000;
+ while (in_a_sec > System.currentTimeMillis()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ void compileExpectFailure(String... args) throws Exception {
+ int rc = main.go(args, System.out, System.err);
+ if (rc == 0) throw new Exception("Expected error during compile! Did not fail!");
+ }
+
+ Map<String,Long> collectState(Path dir) throws IOException
+ {
+ final Map<String,Long> files = new HashMap<>();
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis()));
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return files;
+ }
+
+ void verifyThatFilesHaveBeenRemoved(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+
+ Set<String> froms = from.keySet();
+ Set<String> tos = to.keySet();
+
+ if (froms.equals(tos)) {
+ throw new Exception("Expected new state to have fewer files than previous state!");
+ }
+
+ for (String t : tos) {
+ if (!froms.contains(t)) {
+ throw new Exception("Expected "+t+" to exist in previous state!");
+ }
+ }
+
+ for (String f : args) {
+ f = f.replace("/", File.separator);
+ if (!froms.contains(f)) {
+ throw new Exception("Expected "+f+" to exist in previous state!");
+ }
+ if (tos.contains(f)) {
+ throw new Exception("Expected "+f+" to have been removed from the new state!");
+ }
+ }
+
+ if (froms.size() - args.length != tos.size()) {
+ throw new Exception("There are more removed files than the expected list!");
+ }
+ }
+
+ void verifyThatFilesHaveBeenAdded(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+
+ Set<String> froms = from.keySet();
+ Set<String> tos = to.keySet();
+
+ if (froms.equals(tos)) {
+ throw new Exception("Expected new state to have more files than previous state!");
+ }
+
+ for (String t : froms) {
+ if (!tos.contains(t)) {
+ throw new Exception("Expected "+t+" to exist in new state!");
+ }
+ }
+
+ for (String f : args) {
+ f = f.replace("/", File.separator);
+ if (!tos.contains(f)) {
+ throw new Exception("Expected "+f+" to have been added to new state!");
+ }
+ if (froms.contains(f)) {
+ throw new Exception("Expected "+f+" to not exist in previous state!");
+ }
+ }
+
+ if (froms.size() + args.length != tos.size()) {
+ throw new Exception("There are more added files than the expected list!");
+ }
+ }
+
+ void verifyNewerFiles(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+ if (!from.keySet().equals(to.keySet())) {
+ throw new Exception("Expected the set of files to be identical!");
+ }
+ Set<String> files = new HashSet<String>();
+ for (String s : args) {
+ files.add(s.replace("/", File.separator));
+ }
+ for (String fn : from.keySet()) {
+ long f = from.get(fn);
+ long t = to.get(fn);
+ if (files.contains(fn)) {
+ if (t <= f) {
+ throw new Exception("Expected "+fn+" to have a more recent timestamp!");
+ }
+ } else {
+ if (t != f) {
+ throw new Exception("Expected "+fn+" to have the same timestamp!");
+ }
+ }
+ }
+ }
+
+ String print(Map<String,Long> m) {
+ StringBuilder b = new StringBuilder();
+ Set<String> keys = m.keySet();
+ for (String k : keys) {
+ b.append(k+" "+m.get(k)+"\n");
+ }
+ return b.toString();
+ }
+
+ void verifyEqual(Map<String,Long> from, Map<String,Long> to) throws Exception {
+ if (!from.equals(to)) {
+ System.out.println("FROM---"+print(from));
+ System.out.println("TO-----"+print(to));
+ throw new Exception("The dir should not differ! But it does!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SJavacWrapper.java Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test all aspects of sjavac.
+ *
+ * @bug 8004658
+ * @summary Add internal smart javac wrapper to solve JEP 139
+ *
+ * @run main SJavacWrapper
+ */
+
+import java.io.*;
+import java.lang.reflect.Method;
+import java.net.*;
+
+
+public
+class SJavacWrapper {
+
+ public static void main(String... args) throws Exception {
+ URL url = SJavacWrapper.class.getClassLoader().getResource("com/sun/tools/sjavac/Main.class");
+ if (url == null) {
+ // No sjavac in the classpath.
+ System.out.println("sjavac not available: pass by default");
+ return;
+ }
+
+ File testSrc = new File(System.getProperty("test.src"));
+ File sjavac_java = new File(testSrc, "SJavac.java");
+ File testClasses = new File(System.getProperty("test.classes"));
+ File sjavac_class = new File(testClasses, "SJavac.class");
+ if (sjavac_class.lastModified() < sjavac_java.lastModified()) {
+ String[] javac_args = { "-d", testClasses.getPath(), sjavac_java.getPath() };
+ System.err.println("Recompiling SJavac.java");
+ int rc = com.sun.tools.javac.Main.compile(javac_args);
+ if (rc != 0)
+ throw new Exception("compilation failed");
+ }
+
+ Class<?> sjavac = Class.forName("SJavac");
+ Method sjavac_main = sjavac.getMethod("main", String[].class);
+ sjavac_main.invoke(null, new Object[] { args });
+ }
+
+}