Mercurial > hg > openjdk > jigsaw > langtools
changeset 1798:65e1ca8dcdc7
Merge
author | mfang |
---|---|
date | Mon, 25 Mar 2013 18:08:47 -0700 |
parents | f4500abff1fd (diff) fdf30b225e1c (current diff) |
children | 28e466e9cd34 330b35b27e68 |
files | |
diffstat | 103 files changed, 4345 insertions(+), 2334 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Mar 25 16:55:14 2013 -0700 +++ b/.hgtags Mon Mar 25 18:08:47 2013 -0700 @@ -201,3 +201,5 @@ 89c66415168925dffe492356ff893ff248bb5603 jdk8-b77 af8417e590f4e76e0dfed09e71239fb102ef0d43 jdk8-b78 56dfafbb9e1ad7548a4415316dc003296fb498cb jdk8-b79 +a8227c61768499dac847ea718af6719027c949f2 jdk8-b80 +ed69d087fdfd394491657a28ba9bc58e7849b7db jdk8-b81
--- a/make/build.xml Mon Mar 25 16:55:14 2013 -0700 +++ b/make/build.xml Mon Mar 25 18:08:47 2013 -0700 @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - 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 @@ -432,6 +432,31 @@ </zip> </target> + <target name="doclint-api" depends="build-all-classes"> + <delete dir="${build.dir}/doclint/classes"/> + <mkdir dir="${build.dir}/doclint/classes"/> + <javac fork="true" + executable="${boot.javac}" + srcdir="${src.classes.dir}:${build.gensrc.dir}" + destdir="${build.dir}/doclint/classes" + includes="javax/lang/model/** com/sun/javadoc/** com/sun/source/**" + excludes="" + sourcepath="${javac.sourcepath}" + classpath="${javac.classpath}" + includeAntRuntime="no" + source="${javac.source}" + target="${javac.target}" + debug="${javac.debug}" + debuglevel="${javac.debuglevel}"> + <compilerarg value="-implicit:none"/> + <compilerarg value="-Xprefer:source"/> + <compilerarg value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/> + <compilerarg line="${javac.no.jdk.warnings}"/> + <compilerarg line="${javac.version.opt}"/> + <compilerarg line="-Xdoclint:all/protected,-missing"/> + </javac> + </target> + <!-- **** Debugging/diagnostic targets. --> @@ -678,7 +703,7 @@ jarclasspath="sjavac.jar"/> <build-tool name="sjavac"/> </target> - + <!-- (no javadoc for javap) --> <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
--- a/make/netbeans/langtools/nbproject/project.xml Mon Mar 25 16:55:14 2013 -0700 +++ b/make/netbeans/langtools/nbproject/project.xml Mon Mar 25 18:08:47 2013 -0700 @@ -29,15 +29,13 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - -<!DOCTYPE project [ - <!ENTITY standard-ide-actions SYSTEM "standard-ide-actions.ent"> - <!ENTITY standard-context-menu-items SYSTEM "standard-context-menu-items.ent"> -]> <project xmlns="http://www.netbeans.org/ns/project/1"> <type>org.netbeans.modules.ant.freeform</type> <configuration> <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1"> + <name>langtools</name> + </general-data> + <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2"> <!-- Do not use Project Properties customizer when editing this file manually. --> <name>langtools</name> <properties> @@ -49,11 +47,6 @@ <location>${root}</location> </source-folder> <source-folder> - <label>Source files</label> - <type>java</type> - <location>${root}/src/share/classes</location> - </source-folder> - <source-folder> <label>Test files</label> <type>tests</type> <location>${root}/test</location> @@ -63,9 +56,169 @@ <type>build</type> <location>${root}/make</location> </source-folder> + <source-folder> + <label>Source files</label> + <type>java</type> + <location>${root}/src/share/classes</location> + </source-folder> + <build-file> + <location>${root}/build/classes</location> + </build-file> </folders> <ide-actions> - &standard-ide-actions; + <!-- + Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of Oracle nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + <!-- + This file defines the standard actions accepted by langtools projects. + It is normally included as an entity into a project's project.xml file. + + For information on these actions, see + - NetBeans: Setting Up Projects + at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html + - NetBeans: Advanced Freeform Project Configuration + at http://www.netbeans.org/kb/41/freeform-config.html +--> + <action name="build"> + <target>build</target> + </action> + <action name="clean"> + <target>clean</target> + </action> + <action name="rebuild"> + <target>clean</target> + <target>build</target> + </action> + <action name="compile.single"> + <target>compile-single</target> + <property name="srcdir">${root}/src/share/classes</property> + <context> + <property>includes</property> + <folder>${root}/src/share/classes</folder> + <pattern>\.java$</pattern> + <format>relative-path</format> + <arity> + <separated-files>,</separated-files> + </arity> + </context> + </action> + <action name="run"> + <target>run</target> + </action> + <action name="run.single"> + <target>run-single</target> + <context> + <property>run.classname</property> + <folder>${root}/src/share/classes</folder> + <pattern>\.java$</pattern> + <format>java-name</format> + <arity> + <one-file-only/> + </arity> + </context> + </action> + <!-- + Note: NetBeans does not appear to support context menu items + on shell scripts :-( +--> + <action name="run.single"> + <target>jtreg</target> + <context> + <property>jtreg.tests</property> + <folder>${root}/test</folder> + <pattern>\.(java|sh)$</pattern> + <format>relative-path</format> + <arity> + <separated-files>,</separated-files> + </arity> + </context> + </action> + <action name="test"> + <target>jtreg</target> + </action> + <action name="debug"> + <target>debug</target> + </action> + <action name="debug.single"> + <target>debug-single</target> + <context> + <property>debug.classname</property> + <folder>${root}/src/share/classes</folder> + <pattern>\.java$</pattern> + <format>java-name</format> + <arity> + <one-file-only/> + </arity> + </context> + </action> + <!-- + Note: NetBeans does not appear to support context menu items + on shell scripts :-( +--> + <action name="debug.single"> + <target>debug-jtreg</target> + <context> + <property>jtreg.tests</property> + <folder>${root}/test</folder> + <pattern>\.(java|sh)$</pattern> + <format>relative-path</format> + <arity> + <one-file-only/> + </arity> + </context> + </action> + <action name="debug.fix"> + <target>debug-fix</target> + <property name="srcdir">${root}/src/share/classes</property> + <context> + <property>class</property> + <folder>${root}/src/share/classes</folder> + <pattern>\.java$</pattern> + <format>relative-path-noext</format> + <arity> + <one-file-only/> + </arity> + </context> + </action> + <action name="javadoc"> + <target>javadoc</target> + </action> + <action name="select-tool"> + <target>select-tool</target> + </action> + <action name="test-select-tool-1"> + <target>test-select-tool-1</target> + </action> + <action name="test-select-tool-2"> + <target>test-select-tool-2</target> + </action> </ide-actions> <export> <type>folder</type> @@ -86,13 +239,68 @@ <label>Build files</label> <location>${root}/make</location> </source-folder> + <source-folder style="packages"> + <label>Source files</label> + <location>${root}/src/share/classes</location> + </source-folder> <source-file> <label>README</label> <location>README</location> </source-file> </items> <context-menu> - &standard-context-menu-items; + <!-- + Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of Oracle nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + <!-- + This file defines the actions that will appear on the project's context + menu, in the Projects viewer. + It is normally included as an entity into a project's project.xml file. + + For information on these actions, see + - NetBeans: Setting Up Projects + at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html + - NetBeans: Advanced Freeform Project Configuration + at http://www.netbeans.org/kb/41/freeform-config.html +--> + <ide-action name="select-tool"/> + <separator/> + <ide-action name="build"/> + <ide-action name="rebuild"/> + <ide-action name="clean"/> + <ide-action name="javadoc"/> + <separator/> + <ide-action name="run"/> + <ide-action name="debug"/> + <separator/> + <ide-action name="test"/> </context-menu> </view> <subprojects/> @@ -101,7 +309,7 @@ <compilation-unit> <package-root>${root}/src/share/classes</package-root> <built-to>${root}/build/classes</built-to> - <source-level>1.5</source-level> <!-- FIXME --> + <source-level>1.5</source-level> </compilation-unit> </java-data> </configuration>
--- a/src/share/classes/com/sun/source/util/DocTreeScanner.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/source/util/DocTreeScanner.java Mon Mar 25 18:08:47 2013 -0700 @@ -53,7 +53,7 @@ * * <p>Here is an example to count the number of erroneous nodes in a tree: * <pre> - * class CountErrors extends DocTreeScanner<Integer,Void> { + * class CountErrors extends DocTreeScanner<Integer,Void> { * {@literal @}Override * public Integer visitErroneous(ErroneousTree node, Void p) { * return 1;
--- a/src/share/classes/com/sun/source/util/JavacTask.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/source/util/JavacTask.java Mon Mar 25 18:08:47 2013 -0700 @@ -56,7 +56,7 @@ * If the compiler is being invoked using a * {@link javax.tools.JavaCompiler.CompilationTask CompilationTask}, * then that task will be returned. - * @param processingEnvironment + * @param processingEnvironment the processing environment * @return the {@code JavacTask} for a {@code ProcessingEnvironment} * @since 1.8 */
--- a/src/share/classes/com/sun/source/util/Plugin.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/source/util/Plugin.java Mon Mar 25 18:08:47 2013 -0700 @@ -38,7 +38,7 @@ * * <p>Plug-ins are located via a {@link ServiceLoader}, * using the same class path as annotation processors (i.e. - * {@link StandardLocation#PROCESSOR_PATH PROCESSOR_PATH} or + * {@link StandardLocation#ANNOTATION_PROCESSOR_PATH ANNOTATION_PROCESSOR_PATH} or * {@code -processorpath}). * * <p>It is expected that a typical plug-in will simply register a
--- a/src/share/classes/com/sun/tools/classfile/Code_attribute.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/classfile/Code_attribute.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2009, 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 @@ -38,7 +38,7 @@ * deletion without notice.</b> */ public class Code_attribute extends Attribute { - public class InvalidIndex extends AttributeException { + public static class InvalidIndex extends AttributeException { private static final long serialVersionUID = -8904527774589382802L; InvalidIndex(int index) { this.index = index; @@ -143,7 +143,7 @@ public final Exception_data[] exception_table; public final Attributes attributes; - public class Exception_data { + public static class Exception_data { Exception_data(ClassReader cr) throws IOException { start_pc = cr.readUnsignedShort(); end_pc = cr.readUnsignedShort();
--- a/src/share/classes/com/sun/tools/classfile/Descriptor.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/classfile/Descriptor.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -37,7 +37,7 @@ * deletion without notice.</b> */ public class Descriptor { - public class InvalidDescriptor extends DescriptorException { + public static class InvalidDescriptor extends DescriptorException { private static final long serialVersionUID = 1L; InvalidDescriptor(String desc) { this.desc = desc;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java Mon Mar 25 18:08:47 2013 -0700 @@ -135,13 +135,7 @@ protected Content getFrameDetails() { HtmlTree frameset = HtmlTree.FRAMESET("20%,80%", null, "Documentation frame", "top.loadFrames()"); - if (configuration.showProfiles) { - HtmlTree leftFrameset = HtmlTree.FRAMESET(null, "30%,70%", "Left frames", - "top.loadFrames()"); - addAllProfilesFrameTag(leftFrameset); - addAllClassesFrameTag(leftFrameset); - frameset.addContent(leftFrameset); - } else if (noOfPackages <= 1) { + if (noOfPackages <= 1) { addAllClassesFrameTag(frameset); } else if (noOfPackages > 1) { HtmlTree leftFrameset = HtmlTree.FRAMESET(null, "30%,70%", "Left frames", @@ -156,17 +150,6 @@ } /** - * Add the FRAME tag for the frame that lists all profiles. - * - * @param contentTree the content tree to which the information will be added - */ - private void addAllProfilesFrameTag(Content contentTree) { - HtmlTree frame = HtmlTree.FRAME(DocPaths.PROFILE_OVERVIEW_FRAME.getPath(), - "profileListFrame", configuration.getText("doclet.All_Profiles")); - contentTree.addContent(frame); - } - - /** * Add the FRAME tag for the frame that lists all packages. * * @param contentTree the content tree to which the information will be added
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java Mon Mar 25 18:08:47 2013 -0700 @@ -162,7 +162,7 @@ */ protected void addAllProfilesLink(Content div) { Content linkContent = getHyperLink(DocPaths.PROFILE_OVERVIEW_FRAME, - allprofilesLabel, "", "profileListFrame"); + allprofilesLabel, "", "packageListFrame"); Content span = HtmlTree.SPAN(linkContent); div.addContent(span); }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Mon Mar 25 18:08:47 2013 -0700 @@ -107,7 +107,7 @@ String profileName = (Profile.lookup(profile)).name; profileLabel = new StringContent(profileName); profileLinkContent = getHyperLink(DocPaths.profileFrame(profileName), profileLabel, "", - "profileListFrame"); + "packageListFrame"); Content li = HtmlTree.LI(profileLinkContent); return li; } @@ -154,7 +154,7 @@ */ protected void addAllPackagesLink(Content div) { Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME, - allpackagesLabel, "", "profileListFrame"); + allpackagesLabel, "", "packageListFrame"); Content span = HtmlTree.SPAN(linkContent); div.addContent(span); }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java Mon Mar 25 18:08:47 2013 -0700 @@ -172,7 +172,7 @@ */ protected void addAllPackagesLink(Content div) { Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME, - allpackagesLabel, "", "profileListFrame"); + allpackagesLabel, "", "packageListFrame"); Content span = HtmlTree.SPAN(linkContent); div.addContent(span); } @@ -185,7 +185,7 @@ */ protected void addAllProfilesLink(Content div) { Content linkContent = getHyperLink(DocPaths.PROFILE_OVERVIEW_FRAME, - allprofilesLabel, "", "profileListFrame"); + allprofilesLabel, "", "packageListFrame"); Content span = HtmlTree.SPAN(linkContent); div.addContent(span); }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Mon Mar 25 18:08:47 2013 -0700 @@ -56,7 +56,7 @@ /** * Exception used to report a problem during setOptions. */ - public class Fault extends Exception { + public static class Fault extends Exception { private static final long serialVersionUID = 0; Fault(String msg) {
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,9 +116,9 @@ * @param contentTree the content tree to which the documentation will be added */ public void buildAnnotationTypeDoc(XMLNode node, Content contentTree) throws Exception { - contentTree = writer.getHeader(configuration.getText("doclet.AnnotationType") + + contentTree = writer.getHeader(configuration.getText("doclet.AnnotationType") + " " + annotationTypeDoc.name()); - Content annotationContentTree = writer.getAnnotationContentHeader(); + Content annotationContentTree = writer.getAnnotationContentHeader(); buildChildren(node, annotationContentTree); contentTree.addContent(annotationContentTree); writer.addFooter(contentTree);
--- a/src/share/classes/com/sun/tools/doclint/Checker.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclint/Checker.java Mon Mar 25 18:08:47 2013 -0700 @@ -25,20 +25,18 @@ package com.sun.tools.doclint; -import com.sun.source.doctree.LiteralTree; -import java.util.regex.Matcher; -import com.sun.source.doctree.LinkTree; +import java.io.IOException; +import java.io.StringWriter; import java.net.URI; -import java.util.regex.Pattern; -import java.io.IOException; -import com.sun.tools.javac.tree.DocPretty; -import java.io.StringWriter; +import java.net.URISyntaxException; import java.util.Deque; import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -52,12 +50,15 @@ import com.sun.source.doctree.AttributeTree; import com.sun.source.doctree.AuthorTree; import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.DocRootTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.EndElementTree; import com.sun.source.doctree.EntityTree; import com.sun.source.doctree.ErroneousTree; import com.sun.source.doctree.IdentifierTree; import com.sun.source.doctree.InheritDocTree; +import com.sun.source.doctree.LinkTree; +import com.sun.source.doctree.LiteralTree; import com.sun.source.doctree.ParamTree; import com.sun.source.doctree.ReferenceTree; import com.sun.source.doctree.ReturnTree; @@ -67,11 +68,12 @@ import com.sun.source.doctree.StartElementTree; import com.sun.source.doctree.TextTree; import com.sun.source.doctree.ThrowsTree; +import com.sun.source.doctree.ValueTree; import com.sun.source.doctree.VersionTree; import com.sun.source.util.DocTreeScanner; import com.sun.source.util.TreePath; import com.sun.tools.doclint.HtmlTag.AttrKind; -import java.net.URISyntaxException; +import com.sun.tools.javac.tree.DocPretty; import static com.sun.tools.doclint.Messages.Group.*; @@ -95,6 +97,7 @@ public enum Flag { TABLE_HAS_CAPTION, HAS_ELEMENT, + HAS_INLINE_TAG, HAS_TEXT, REPORTED_BAD_INLINE } @@ -418,7 +421,8 @@ } if (t.flags.contains(HtmlTag.Flag.EXPECT_CONTENT) && !top.flags.contains(Flag.HAS_TEXT) - && !top.flags.contains(Flag.HAS_ELEMENT)) { + && !top.flags.contains(Flag.HAS_ELEMENT) + && !top.flags.contains(Flag.HAS_INLINE_TAG)) { env.messages.warning(HTML, tree, "dc.tag.empty", treeName); } tagStack.pop(); @@ -571,7 +575,14 @@ } @Override + public Void visitDocRoot(DocRootTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_INLINE_TAG); + return super.visitDocRoot(tree, ignore); + } + + @Override public Void visitInheritDoc(InheritDocTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_INLINE_TAG); // TODO: verify on overridden method foundInheritDoc = true; return super.visitInheritDoc(tree, ignore); @@ -579,6 +590,7 @@ @Override public Void visitLink(LinkTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_INLINE_TAG); // simulate inline context on tag stack HtmlTag t = (tree.getKind() == DocTree.Kind.LINK) ? HtmlTag.CODE : HtmlTag.SPAN; @@ -592,6 +604,7 @@ @Override public Void visitLiteral(LiteralTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_INLINE_TAG); if (tree.getKind() == DocTree.Kind.CODE) { for (TagStackItem tsi: tagStack) { if (tsi.tag == HtmlTag.CODE) { @@ -746,6 +759,12 @@ } @Override + public Void visitValue(ValueTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_INLINE_TAG); + return super.visitValue(tree, ignore); + } + + @Override public Void visitVersion(VersionTree tree, Void ignore) { warnIfEmpty(tree, tree.getBody()); return super.visitVersion(tree, ignore);
--- a/src/share/classes/com/sun/tools/javac/Server.java Mon Mar 25 16:55:14 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.logging.Logger; -import javax.tools.*; - -/** - * Java Compiler Server. Can be used to speed up a set of (small) - * compilation tasks by caching jar files between compilations. - * - * <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> - * - * @author Peter von der Ahé - * @since 1.6 - */ -@jdk.Supported(false) -class Server implements Runnable { - private final BufferedReader in; - private final OutputStream out; - private final boolean isSocket; - private static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - private static final Logger logger = Logger.getLogger("com.sun.tools.javac"); - static class CwdFileManager extends ForwardingJavaFileManager<JavaFileManager> { - String cwd; - CwdFileManager(JavaFileManager fileManager) { - super(fileManager); - } - String getAbsoluteName(String name) { - if (new File(name).isAbsolute()) { - return name; - } else { - return new File(cwd,name).getPath(); - } - } -// public JavaFileObject getFileForInput(String name) -// throws IOException -// { -// return super.getFileForInput(getAbsoluteName(name)); -// } - } - // static CwdFileManager fm = new CwdFileManager(tool.getStandardFileManager()); - static final StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - static { - // Use the same file manager for all compilations. This will - // cache jar files in the standard file manager. Use - // tool.getStandardFileManager().close() to release. - // FIXME tool.setFileManager(fm); - logger.setLevel(java.util.logging.Level.SEVERE); - } - private Server(BufferedReader in, OutputStream out, boolean isSocket) { - this.in = in; - this.out = out; - this.isSocket = isSocket; - } - private Server(BufferedReader in, OutputStream out) { - this(in, out, false); - } - private Server(Socket socket) throws IOException, UnsupportedEncodingException { - this(new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8")), - socket.getOutputStream(), - true); - } - public void run() { - List<String> args = new ArrayList<String>(); - int res = -1; - try { - String line = null; - try { - line = in.readLine(); - } catch (IOException e) { - System.err.println(e.getLocalizedMessage()); - System.exit(0); - line = null; - } - // fm.cwd=null; - String cwd = null; - while (line != null) { - if (line.startsWith("PWD:")) { - cwd = line.substring(4); - } else if (line.equals("END")) { - break; - } else if (!"-XDstdout".equals(line)) { - args.add(line); - } - try { - line = in.readLine(); - } catch (IOException e) { - System.err.println(e.getLocalizedMessage()); - System.exit(0); - line = null; - } - } - Iterable<File> path = cwd == null ? null : Arrays.<File>asList(new File(cwd)); - // try { in.close(); } catch (IOException e) {} - long msec = System.currentTimeMillis(); - try { - synchronized (tool) { - for (StandardLocation location : StandardLocation.values()) - fm.setLocation(location, path); - res = compile(out, fm, args); - // FIXME res = tool.run((InputStream)null, null, out, args.toArray(new String[args.size()])); - } - } catch (Throwable ex) { - logger.log(java.util.logging.Level.SEVERE, args.toString(), ex); - PrintWriter p = new PrintWriter(out, true); - ex.printStackTrace(p); - p.flush(); - } - if (res >= 3) { - logger.severe(String.format("problem: %s", args)); - } else { - logger.info(String.format("success: %s", args)); - } - // res = compile(args.toArray(new String[args.size()]), out); - msec -= System.currentTimeMillis(); - logger.info(String.format("Real time: %sms", -msec)); - } finally { - if (!isSocket) { - try { in.close(); } catch (IOException e) {} - } - try { - out.write(String.format("EXIT: %s%n", res).getBytes()); - } catch (IOException ex) { - logger.log(java.util.logging.Level.SEVERE, args.toString(), ex); - } - try { - out.flush(); - out.close(); - } catch (IOException ex) { - logger.log(java.util.logging.Level.SEVERE, args.toString(), ex); - } - logger.info(String.format("EXIT: %s", res)); - } - } - public static void main(String... args) throws FileNotFoundException { - if (args.length == 2) { - for (;;) { - throw new UnsupportedOperationException("TODO"); -// BufferedReader in = new BufferedReader(new FileReader(args[0])); -// PrintWriter out = new PrintWriter(args[1]); -// new Server(in, out).run(); -// System.out.flush(); -// System.err.flush(); - } - } else { - ExecutorService pool = Executors.newCachedThreadPool(); - try - { - ServerSocket socket = new ServerSocket(0xcafe, -1, null); - for (;;) { - pool.execute(new Server(socket.accept())); - } - } - catch (IOException e) { - System.err.format("Error: %s%n", e.getLocalizedMessage()); - pool.shutdown(); - } - } - } - - private int compile(OutputStream out, StandardJavaFileManager fm, List<String> args) { - // FIXME parse args and use getTask - // System.err.println("Running " + args); - return tool.run(null, null, out, args.toArray(new String[args.size()])); - } -}
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Printer.java Mon Mar 25 18:08:47 2013 -0700 @@ -311,9 +311,9 @@ } if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) { buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale)); - if (args.head.getAnnotations().nonEmpty()) { + if (args.head.getAnnotationMirrors().nonEmpty()) { buf.append(' '); - buf.append(args.head.getAnnotations()); + buf.append(args.head.getAnnotationMirrors()); buf.append(' '); } buf.append("...");
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Mar 25 18:08:47 2013 -0700 @@ -483,12 +483,12 @@ */ @Deprecated public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { - return JavacElements.getAnnotation(this, annoType); + return JavacAnnoConstructs.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[] getAnnotationsByType(Class<A> annoType) { - return JavacElements.getAnnotations(this, annoType); + return JavacAnnoConstructs.getAnnotations(this, annoType); } // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList @@ -935,11 +935,12 @@ } /** - * @deprecated this method should never be used by javac internally. + * Since this method works in terms of the runtime representation + * of annotations, it should never be used by javac internally. */ - @Override @Deprecated + @Override public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { - return JavacElements.getAnnotation(this, annoType); + return JavacAnnoConstructs.getAnnotation(this, annoType); } public <R, P> R accept(ElementVisitor<R, P> v, P p) { @@ -1444,6 +1445,10 @@ return v.visitMethodSymbol(this, p); } + public Type getReceiverType() { + return asType().getReceiverType(); + } + public Type getReturnType() { return asType().getReturnType(); }
--- a/src/share/classes/com/sun/tools/javac/code/Type.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Mon Mar 25 18:08:47 2013 -0700 @@ -25,6 +25,9 @@ package com.sun.tools.javac.code; +import com.sun.tools.javac.model.JavacAnnoConstructs; +import com.sun.tools.javac.model.JavacTypes; +import java.lang.annotation.Annotation; import java.util.Collections; import java.util.EnumMap; import java.util.EnumSet; @@ -246,6 +249,10 @@ return this; } + public boolean isAnnotated() { + return false; + } + /** * If this is an annotated type, return the underlying type. * Otherwise, return the type itself. @@ -254,6 +261,23 @@ return this; } + @Override + public List<? extends Attribute.TypeCompound> getAnnotationMirrors() { + return List.nil(); + } + + @Override + public <A extends Annotation> A getAnnotation(Class<A> annotationType) { + return null; + } + + @Override + public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { + @SuppressWarnings("unchecked") + A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0); + return tmp; + } + /** Return the base types of a list of types. */ public static List<Type> baseTypes(List<Type> ts) { @@ -350,8 +374,8 @@ } if (args.head.unannotatedType().tag == ARRAY) { buf.append(((ArrayType)args.head.unannotatedType()).elemtype); - if (args.head.getAnnotations().nonEmpty()) { - buf.append(args.head.getAnnotations()); + if (args.head.getAnnotationMirrors().nonEmpty()) { + buf.append(args.head.getAnnotationMirrors()); } buf.append("..."); } else { @@ -362,7 +386,6 @@ /** Access methods. */ - public List<? extends AnnotationMirror> getAnnotations() { return List.nil(); } public List<Type> getTypeArguments() { return List.nil(); } public Type getEnclosingType() { return null; } public List<Type> getParameterTypes() { return List.nil(); } @@ -1539,7 +1562,12 @@ } public static class AnnotatedType extends Type - implements javax.lang.model.type.AnnotatedType { + implements + javax.lang.model.type.ArrayType, + javax.lang.model.type.DeclaredType, + javax.lang.model.type.PrimitiveType, + javax.lang.model.type.TypeVariable, + javax.lang.model.type.WildcardType { /** The type annotations on this type. */ public List<Attribute.TypeCompound> typeAnnotations; @@ -1552,7 +1580,7 @@ super(underlyingType.tag, underlyingType.tsym); this.typeAnnotations = List.nil(); this.underlyingType = underlyingType; - Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED, + Assert.check(!underlyingType.isAnnotated(), "Can't annotate already annotated type: " + underlyingType); } @@ -1561,24 +1589,34 @@ super(underlyingType.tag, underlyingType.tsym); this.typeAnnotations = typeAnnotations; this.underlyingType = underlyingType; - Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED, + Assert.check(!underlyingType.isAnnotated(), "Can't annotate already annotated type: " + underlyingType + "; adding: " + typeAnnotations); } @Override - public TypeKind getKind() { - return TypeKind.ANNOTATED; + public boolean isAnnotated() { + return true; } @Override - public List<? extends AnnotationMirror> getAnnotations() { + public List<? extends Attribute.TypeCompound> getAnnotationMirrors() { return typeAnnotations; } @Override - public TypeMirror getUnderlyingType() { - return underlyingType; + public <A extends Annotation> A getAnnotation(Class<A> annotationType) { + return JavacAnnoConstructs.getAnnotation(this, annotationType); + } + + @Override + public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { + return JavacAnnoConstructs.getAnnotationsByType(this, annotationType); + } + + @Override + public TypeKind getKind() { + return underlyingType.getKind(); } @Override @@ -1593,7 +1631,7 @@ @Override public <R, P> R accept(TypeVisitor<R, P> v, P p) { - return v.visitAnnotated(this, p); + return underlyingType.accept(v, p); } @Override
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Mon Mar 25 18:08:47 2013 -0700 @@ -233,7 +233,7 @@ Type.ArrayType arType; { Type touse = type; - if (type.getKind() == TypeKind.ANNOTATED) { + if (type.isAnnotated()) { Type.AnnotatedType atype = (Type.AnnotatedType)type; toreturn = new Type.AnnotatedType(atype.underlyingType); ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations; @@ -252,7 +252,7 @@ ListBuffer<TypePathEntry> depth = ListBuffer.lb(); depth = depth.append(TypePathEntry.ARRAY); while (arType.elemtype.hasTag(TypeTag.ARRAY)) { - if (arType.elemtype.getKind() == TypeKind.ANNOTATED) { + if (arType.elemtype.isAnnotated()) { Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype; Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType); tomodify.elemtype = newAT;
--- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Mar 25 18:08:47 2013 -0700 @@ -1178,6 +1178,17 @@ protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { return isSameTypes(ts1, ts2, true); } + + @Override + public Boolean visitWildcardType(WildcardType t, Type s) { + if (!s.hasTag(WILDCARD)) { + return false; + } else { + WildcardType t2 = (WildcardType)s; + return t.kind == t2.kind && + isSameType(t.type, t2.type, true); + } + } }; // </editor-fold> @@ -1418,23 +1429,10 @@ } } - if (t.isCompound()) { - Warner oldWarner = warnStack.head; - warnStack.head = noWarnings; - if (!visit(supertype(t), s)) - return false; - for (Type intf : interfaces(t)) { - if (!visit(intf, s)) - return false; - } - if (warnStack.head.hasLint(LintCategory.UNCHECKED)) - oldWarner.warn(LintCategory.UNCHECKED); - return true; - } - - if (s.isCompound()) { - // call recursively to reuse the above code - return visitClassType((ClassType)s, t); + if (t.isCompound() || s.isCompound()) { + return !t.isCompound() ? + visitIntersectionType((IntersectionClassType)s, t, true) : + visitIntersectionType((IntersectionClassType)t, s, false); } if (s.tag == CLASS || s.tag == ARRAY) { @@ -1512,6 +1510,18 @@ return false; } + boolean visitIntersectionType(IntersectionClassType ict, Type s, boolean reverse) { + Warner warn = noWarnings; + for (Type c : ict.getComponents()) { + warn.clear(); + if (reverse ? !isCastable(s, c, warn) : !isCastable(c, s, warn)) + return false; + } + if (warn.hasLint(LintCategory.UNCHECKED)) + warnStack.head.warn(LintCategory.UNCHECKED); + return true; + } + @Override public Boolean visitArrayType(ArrayType t, Type s) { switch (s.tag) { @@ -2091,7 +2101,7 @@ @Override public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { Type erased = erasure(t.underlyingType, recurse); - if (erased.getKind() == TypeKind.ANNOTATED) { + if (erased.isAnnotated()) { // This can only happen when the underlying type is a // type variable and the upper bound of it is annotated. // The annotation on the type variable overrides the one @@ -3889,11 +3899,18 @@ } private boolean giveWarning(Type from, Type to) { - Type subFrom = asSub(from, to.tsym); - return to.isParameterized() && - (!(isUnbounded(to) || - isSubtype(from, to) || - ((subFrom != null) && containsType(to.allparams(), subFrom.allparams())))); + List<Type> bounds = to.isCompound() ? + ((IntersectionClassType)to).getComponents() : List.of(to); + for (Type b : bounds) { + Type subFrom = asSub(from, b.tsym); + if (b.isParameterized() && + (!(isUnbounded(b) || + isSubtype(from, b) || + ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) { + return true; + } + } + return false; } private List<Type> superClosure(Type t, Type s) {
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Mar 25 18:08:47 2013 -0700 @@ -3362,7 +3362,7 @@ Type normOuter = site; if (normOuter.hasTag(CLASS)) { normOuter = types.asEnclosingSuper(site, ownOuter.tsym); - if (site.getKind() == TypeKind.ANNOTATED) { + if (site.isAnnotated()) { // Propagate any type annotations. // TODO: should asEnclosingSuper do this? // Note that the type annotations in site will be updated @@ -4009,8 +4009,7 @@ // Enums may not be extended by source-level classes if (st.tsym != null && ((st.tsym.flags_field & Flags.ENUM) != 0) && - ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0) && - !target.compilerBootstrap(c)) { + ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) { log.error(env.tree.pos(), "enum.types.not.extensible"); } attribClassBody(env, c); @@ -4279,7 +4278,7 @@ validateAnnotatedType(errtree, type); if (type.tsym != null && type.tsym.isStatic() && - type.getAnnotations().nonEmpty()) { + type.getAnnotationMirrors().nonEmpty()) { // Enclosing static classes cannot have type annotations. log.error(errtree.pos(), "cant.annotate.static.class"); }
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Mar 25 18:08:47 2013 -0700 @@ -2779,25 +2779,17 @@ } private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { - Attribute.Array containedTarget = getAttributeTargetAttribute(contained); - - // If contained has no Target, we are done - if (containedTarget == null) { - return; - } - - // If contained has Target m1, container must have a Target - // annotation, m2, and m2 must be a subset of m1. (This is - // trivially true if contained has no target as per above). - - // contained has target, but container has not, error + // The set of targets the container is applicable to must be a subset + // (with respect to annotation target semantics) of the set of targets + // the contained is applicable to. The target sets may be implicit or + // explicit. + + Set<Name> containerTargets; Attribute.Array containerTarget = getAttributeTargetAttribute(container); if (containerTarget == null) { - log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); - return; - } - - Set<Name> containerTargets = new HashSet<Name>(); + containerTargets = getDefaultTargetSet(); + } else { + containerTargets = new HashSet<Name>(); for (Attribute app : containerTarget.values) { if (!(app instanceof Attribute.Enum)) { continue; // recovery @@ -2805,8 +2797,14 @@ Attribute.Enum e = (Attribute.Enum)app; containerTargets.add(e.value.name); } - - Set<Name> containedTargets = new HashSet<Name>(); + } + + Set<Name> containedTargets; + Attribute.Array containedTarget = getAttributeTargetAttribute(contained); + if (containedTarget == null) { + containedTargets = getDefaultTargetSet(); + } else { + containedTargets = new HashSet<Name>(); for (Attribute app : containedTarget.values) { if (!(app instanceof Attribute.Enum)) { continue; // recovery @@ -2814,20 +2812,42 @@ Attribute.Enum e = (Attribute.Enum)app; containedTargets.add(e.value.name); } - - if (!isTargetSubset(containedTargets, containerTargets)) { + } + + if (!isTargetSubsetOf(containerTargets, containedTargets)) { log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); } } - /** Checks that t is a subset of s, with respect to ElementType + /* get a set of names for the default target */ + private Set<Name> getDefaultTargetSet() { + if (defaultTargets == null) { + Set<Name> targets = new HashSet<Name>(); + targets.add(names.ANNOTATION_TYPE); + targets.add(names.CONSTRUCTOR); + targets.add(names.FIELD); + targets.add(names.LOCAL_VARIABLE); + targets.add(names.METHOD); + targets.add(names.PACKAGE); + targets.add(names.PARAMETER); + targets.add(names.TYPE); + + defaultTargets = java.util.Collections.unmodifiableSet(targets); + } + + return defaultTargets; + } + private Set<Name> defaultTargets; + + + /** Checks that s is a subset of t, with respect to ElementType * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE} */ - private boolean isTargetSubset(Set<Name> s, Set<Name> t) { - // Check that all elements in t are present in s - for (Name n2 : t) { + private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) { + // Check that all elements in s are present in t + for (Name n2 : s) { boolean currentElementOk = false; - for (Name n1 : s) { + for (Name n1 : t) { if (n1 == n2) { currentElementOk = true; break;
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Mar 25 18:08:47 2013 -0700 @@ -229,9 +229,9 @@ public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { switch (deferredAttrContext.mode) { case SPECULATIVE: - Assert.check(dt.mode == null || - (dt.mode == AttrMode.SPECULATIVE && - dt.speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).hasTag(NONE))); + //Note: if a symbol is imported twice we might do two identical + //speculative rounds... + Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE); JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo); dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase); return speculativeTree.type;
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Mon Mar 25 18:08:47 2013 -0700 @@ -585,11 +585,7 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { - if (!inferenceContext.inferenceVars().contains(b1) && - !inferenceContext.inferenceVars().contains(b2) && - infer.types.asSuper(b2, b1.tsym) != null) { - infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); - } + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); } } } @@ -603,11 +599,7 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.EQ)) { - if (!inferenceContext.inferenceVars().contains(b1) && - !inferenceContext.inferenceVars().contains(b2) && - infer.types.asSuper(b2, b1.tsym) != null) { - infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); - } + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); } } } @@ -621,10 +613,22 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.EQ)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { - if (!inferenceContext.inferenceVars().contains(b1) && - !inferenceContext.inferenceVars().contains(b2) && - infer.types.asSuper(b2, b1.tsym) != null) { - infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); + infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); + } + } + } + }, + /** + * Given a bound set containing {@code alpha == S} and {@code alpha == T} + * perform {@code S == T} (which could lead to new bounds). + */ + CROSS_EQ_EQ() { + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { + Infer infer = inferenceContext.infer(); + for (Type b1 : uv.getBounds(InferenceBound.EQ)) { + for (Type b2 : uv.getBounds(InferenceBound.EQ)) { + if (b1 != b2) { + infer.types.isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); } } }
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Mar 25 18:08:47 2013 -0700 @@ -1019,14 +1019,14 @@ } else if (refSym.enclClass().isInterface()) { return ClassFile.REF_invokeInterface; } else { - return ClassFile.REF_invokeVirtual; + return (refSym.flags() & PRIVATE) != 0 ? + ClassFile.REF_invokeSpecial : + ClassFile.REF_invokeVirtual; } } } - // </editor-fold> - - // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">\ + // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer"> /** * This visitor collects information about translation of a lambda expression. * More specifically, it keeps track of the enclosing contexts and captured locals @@ -1293,9 +1293,16 @@ return names.lambda.append(names.fromString("" + lambdaCount++)); } + /** + * For a serializable lambda, generate a name which maximizes name + * stability across deserialization. + * @param owner + * @return Name to use for the synthetic lambda method name + */ private Name serializedLambdaName(Symbol owner) { StringBuilder buf = new StringBuilder(); buf.append(names.lambda); + // Append the name of the method enclosing the lambda. String methodName = owner.name.toString(); if (methodName.equals("<clinit>")) methodName = "static"; @@ -1303,9 +1310,18 @@ methodName = "new"; buf.append(methodName); buf.append('$'); - int methTypeHash = methodSig(owner.type).hashCode(); - buf.append(Integer.toHexString(methTypeHash)); + // Append a hash of the enclosing method signature to differentiate + // overloaded enclosing methods. For lambdas enclosed in lambdas, + // the generated lambda method will not have type yet, but the + // enclosing method's name will have been generated with this same + // method, so it will be unique and never be overloaded. + if (owner.type != null) { + int methTypeHash = methodSig(owner.type).hashCode(); + buf.append(Integer.toHexString(methTypeHash)); + } buf.append('$'); + // The above appended name components may not be unique, append a + // count based on the above name components. String temp = buf.toString(); Integer count = serializableLambdaCounts.get(temp); if (count == null) { @@ -1619,16 +1635,16 @@ * Translate a symbol of a given kind into something suitable for the * synthetic lambda body */ - Symbol translate(String name, final Symbol sym, LambdaSymbolKind skind) { + Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) { switch (skind) { case CAPTURED_THIS: return sym; // self represented case TYPE_VAR: // Just erase the type var - return new VarSymbol(sym.flags(), names.fromString(name), + return new VarSymbol(sym.flags(), name, types.erasure(sym.type), sym.owner); case CAPTURED_VAR: - return new VarSymbol(SYNTHETIC | FINAL, names.fromString(name), types.erasure(sym.type), translatedSym) { + return new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol @@ -1642,27 +1658,27 @@ void addSymbol(Symbol sym, LambdaSymbolKind skind) { Map<Symbol, Symbol> transMap = null; - String preferredName; + Name preferredName; switch (skind) { case CAPTURED_THIS: transMap = capturedThis; - preferredName = "encl$" + capturedThis.size(); + preferredName = names.fromString("encl$" + capturedThis.size()); break; case CAPTURED_VAR: transMap = capturedLocals; - preferredName = "cap$" + capturedLocals.size(); + preferredName = names.fromString("cap$" + capturedLocals.size()); break; case LOCAL_VAR: transMap = lambdaLocals; - preferredName = sym.name.toString(); + preferredName = sym.name; break; case PARAM: transMap = lambdaParams; - preferredName = sym.name.toString(); + preferredName = sym.name; break; case TYPE_VAR: transMap = typeVars; - preferredName = sym.name.toString(); + preferredName = sym.name; break; default: throw new AssertionError(); }
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Mar 25 18:08:47 2013 -0700 @@ -2604,11 +2604,6 @@ enumDefs.appendList(otherDefs.toList()); tree.defs = enumDefs.toList(); - - // Add the necessary members for the EnumCompatibleMode - if (target.compilerBootstrap(tree.sym)) { - addEnumCompatibleMembers(tree); - } } // where private MethodSymbol systemArraycopyMethod; @@ -2657,30 +2652,6 @@ olderasure.getReturnType(), olderasure.getThrownTypes(), syms.methodClass); - - if (target.compilerBootstrap(m.owner)) { - // Initialize synthetic name field - Symbol nameVarSym = lookupSynthetic(names.fromString("$name"), - tree.sym.owner.members()); - JCIdent nameIdent = make.Ident(nameParam.sym); - JCIdent id1 = make.Ident(nameVarSym); - JCAssign newAssign = make.Assign(id1, nameIdent); - newAssign.type = id1.type; - JCExpressionStatement nameAssign = make.Exec(newAssign); - nameAssign.type = id1.type; - tree.body.stats = tree.body.stats.prepend(nameAssign); - - // Initialize synthetic ordinal field - Symbol ordinalVarSym = lookupSynthetic(names.fromString("$ordinal"), - tree.sym.owner.members()); - JCIdent ordIdent = make.Ident(ordParam.sym); - id1 = make.Ident(ordinalVarSym); - newAssign = make.Assign(id1, ordIdent); - newAssign.type = id1.type; - JCExpressionStatement ordinalAssign = make.Exec(newAssign); - ordinalAssign.type = id1.type; - tree.body.stats = tree.body.stats.prepend(ordinalAssign); - } } JCMethodDecl prevMethodDef = currentMethodDef; @@ -3434,14 +3405,16 @@ tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr); Symbol iterator = lookupMethod(tree.expr.pos(), names.iterator, - types.erasure(syms.iterableType), + eType, List.<Type>nil()); VarSymbol itvar = new VarSymbol(0, names.fromString("i" + target.syntheticNameChar()), types.erasure(iterator.type.getReturnType()), currentMethodSym); - JCStatement init = make. - VarDef(itvar, - make.App(make.Select(tree.expr, iterator))); + + JCStatement init = make. + VarDef(itvar, make.App(make.Select(tree.expr, iterator) + .setType(types.erasure(iterator.type)))); + Symbol hasNext = lookupMethod(tree.expr.pos(), names.hasNext, itvar.type, @@ -3886,168 +3859,4 @@ } return translated.toList(); } - - ////////////////////////////////////////////////////////////// - // The following contributed by Borland for bootstrapping purposes - ////////////////////////////////////////////////////////////// - private void addEnumCompatibleMembers(JCClassDecl cdef) { - make_at(null); - - // Add the special enum fields - VarSymbol ordinalFieldSym = addEnumOrdinalField(cdef); - VarSymbol nameFieldSym = addEnumNameField(cdef); - - // Add the accessor methods for name and ordinal - MethodSymbol ordinalMethodSym = addEnumFieldOrdinalMethod(cdef, ordinalFieldSym); - MethodSymbol nameMethodSym = addEnumFieldNameMethod(cdef, nameFieldSym); - - // Add the toString method - addEnumToString(cdef, nameFieldSym); - - // Add the compareTo method - addEnumCompareTo(cdef, ordinalFieldSym); - } - - private VarSymbol addEnumOrdinalField(JCClassDecl cdef) { - VarSymbol ordinal = new VarSymbol(PRIVATE|FINAL|SYNTHETIC, - names.fromString("$ordinal"), - syms.intType, - cdef.sym); - cdef.sym.members().enter(ordinal); - cdef.defs = cdef.defs.prepend(make.VarDef(ordinal, null)); - return ordinal; - } - - private VarSymbol addEnumNameField(JCClassDecl cdef) { - VarSymbol name = new VarSymbol(PRIVATE|FINAL|SYNTHETIC, - names.fromString("$name"), - syms.stringType, - cdef.sym); - cdef.sym.members().enter(name); - cdef.defs = cdef.defs.prepend(make.VarDef(name, null)); - return name; - } - - private MethodSymbol addEnumFieldOrdinalMethod(JCClassDecl cdef, VarSymbol ordinalSymbol) { - // Add the accessor methods for ordinal - Symbol ordinalSym = lookupMethod(cdef.pos(), - names.ordinal, - cdef.type, - List.<Type>nil()); - - Assert.check(ordinalSym instanceof MethodSymbol); - - JCStatement ret = make.Return(make.Ident(ordinalSymbol)); - cdef.defs = cdef.defs.append(make.MethodDef((MethodSymbol)ordinalSym, - make.Block(0L, List.of(ret)))); - - return (MethodSymbol)ordinalSym; - } - - private MethodSymbol addEnumFieldNameMethod(JCClassDecl cdef, VarSymbol nameSymbol) { - // Add the accessor methods for name - Symbol nameSym = lookupMethod(cdef.pos(), - names._name, - cdef.type, - List.<Type>nil()); - - Assert.check(nameSym instanceof MethodSymbol); - - JCStatement ret = make.Return(make.Ident(nameSymbol)); - - cdef.defs = cdef.defs.append(make.MethodDef((MethodSymbol)nameSym, - make.Block(0L, List.of(ret)))); - - return (MethodSymbol)nameSym; - } - - private MethodSymbol addEnumToString(JCClassDecl cdef, - VarSymbol nameSymbol) { - Symbol toStringSym = lookupMethod(cdef.pos(), - names.toString, - cdef.type, - List.<Type>nil()); - - JCTree toStringDecl = null; - if (toStringSym != null) - toStringDecl = TreeInfo.declarationFor(toStringSym, cdef); - - if (toStringDecl != null) - return (MethodSymbol)toStringSym; - - JCStatement ret = make.Return(make.Ident(nameSymbol)); - - JCTree resTypeTree = make.Type(syms.stringType); - - MethodType toStringType = new MethodType(List.<Type>nil(), - syms.stringType, - List.<Type>nil(), - cdef.sym); - toStringSym = new MethodSymbol(PUBLIC, - names.toString, - toStringType, - cdef.type.tsym); - toStringDecl = make.MethodDef((MethodSymbol)toStringSym, - make.Block(0L, List.of(ret))); - - cdef.defs = cdef.defs.prepend(toStringDecl); - cdef.sym.members().enter(toStringSym); - - return (MethodSymbol)toStringSym; - } - - private MethodSymbol addEnumCompareTo(JCClassDecl cdef, VarSymbol ordinalSymbol) { - Symbol compareToSym = lookupMethod(cdef.pos(), - names.compareTo, - cdef.type, - List.of(cdef.sym.type)); - - Assert.check(compareToSym instanceof MethodSymbol); - - JCMethodDecl compareToDecl = (JCMethodDecl) TreeInfo.declarationFor(compareToSym, cdef); - - ListBuffer<JCStatement> blockStatements = new ListBuffer<JCStatement>(); - - JCModifiers mod1 = make.Modifiers(0L); - Name oName = names.fromString("o"); - JCVariableDecl par1 = make.Param(oName, cdef.type, compareToSym); - - JCIdent paramId1 = make.Ident(names.java_lang_Object); - paramId1.type = cdef.type; - paramId1.sym = par1.sym; - - ((MethodSymbol)compareToSym).params = List.of(par1.sym); - - JCIdent par1UsageId = make.Ident(par1.sym); - JCIdent castTargetIdent = make.Ident(cdef.sym); - JCTypeCast cast = make.TypeCast(castTargetIdent, par1UsageId); - cast.setType(castTargetIdent.type); - - Name otherName = names.fromString("other"); - - VarSymbol otherVarSym = new VarSymbol(mod1.flags, - otherName, - cdef.type, - compareToSym); - JCVariableDecl otherVar = make.VarDef(otherVarSym, cast); - blockStatements.append(otherVar); - - JCIdent id1 = make.Ident(ordinalSymbol); - - JCIdent fLocUsageId = make.Ident(otherVarSym); - JCExpression sel = make.Select(fLocUsageId, ordinalSymbol); - JCBinary bin = makeBinary(MINUS, id1, sel); - JCReturn ret = make.Return(bin); - blockStatements.append(ret); - JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym, - make.Block(0L, - blockStatements.toList())); - compareToMethod.params = List.of(par1); - cdef.defs = cdef.defs.append(compareToMethod); - - return (MethodSymbol)compareToSym; - } - ////////////////////////////////////////////////////////////// - // The above contributed by Borland for bootstrapping purposes - ////////////////////////////////////////////////////////////// }
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Mar 25 18:08:47 2013 -0700 @@ -473,44 +473,6 @@ null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))), null); memberEnter(valueOf, env); - - // the remaining members are for bootstrapping only - if (!target.compilerBootstrap(tree.sym)) return; - - // public final int ordinal() { return ???; } - JCMethodDecl ordinal = make.at(tree.pos). - MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL), - names.ordinal, - make.Type(syms.intType), - List.<JCTypeParameter>nil(), - List.<JCVariableDecl>nil(), - List.<JCExpression>nil(), - null, - null); - memberEnter(ordinal, env); - - // public final String name() { return ???; } - JCMethodDecl name = make. - MethodDef(make.Modifiers(Flags.PUBLIC|Flags.FINAL), - names._name, - make.Type(syms.stringType), - List.<JCTypeParameter>nil(), - List.<JCVariableDecl>nil(), - List.<JCExpression>nil(), - null, - null); - memberEnter(name, env); - - // public int compareTo(E other) { return ???; } - MethodSymbol compareTo = new - MethodSymbol(Flags.PUBLIC, - names.compareTo, - new MethodType(List.of(tree.sym.type), - syms.intType, - List.<Type>nil(), - syms.methodClass), - tree.sym); - memberEnter(make.MethodDef(compareTo, null), env); } public void visitTopLevel(JCCompilationUnit tree) { @@ -936,7 +898,7 @@ Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) - : ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c)) + : ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) @@ -949,16 +911,6 @@ ListBuffer<Type> all_interfaces = null; // lazy init Set<Type> interfaceSet = new HashSet<Type>(); List<JCExpression> interfaceTrees = tree.implementing; - if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) { - // add interface Comparable<T> - interfaceTrees = - interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(), - List.of(c.type), - syms.comparableType.tsym))); - // add interface Serializable - interfaceTrees = - interfaceTrees.prepend(make.Type(syms.serializableType)); - } for (JCExpression iface : interfaceTrees) { Type i = attr.attribBase(iface, baseEnv, false, true, true); if (i.hasTag(CLASS)) { @@ -1401,8 +1353,7 @@ if (c.type != syms.objectType) stats = stats.prepend(SuperCall(make, typarams, params, based)); if ((c.flags() & ENUM) != 0 && - (types.supertype(c.type).tsym == syms.enumSym || - target.compilerBootstrap(c))) { + (types.supertype(c.type).tsym == syms.enumSym)) { // constructors of true enums are private flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR; } else
--- a/src/share/classes/com/sun/tools/javac/jvm/Target.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -48,17 +48,6 @@ /** J2SE1.4 = Merlin. */ JDK1_4("1.4", 48, 0), - /** Support for the JSR14 prototype compiler (targeting 1.4 VMs - * augmented with a few support classes). This is a transitional - * option that will not be supported in the product. */ - JSR14("jsr14", 48, 0), - - /** The following are undocumented transitional targets that we - * had used to test VM fixes in update releases. We do not - * promise to retain support for them. */ - JDK1_4_1("1.4.1", 48, 0), - JDK1_4_2("1.4.2", 48, 0), - /** Tiger. */ JDK1_5("1.5", 49, 0), @@ -175,23 +164,23 @@ return compareTo(JDK1_5) >= 0; } - /** Beginning in -target 1.4.2, we make synthetic variables + /** Beginning in -target 1.5, we make synthetic variables * package-private instead of private. This is to prevent the * necessity of access methods, which effectively relax the * protection of the field but bloat the class files and affect * execution. */ public boolean usePrivateSyntheticFields() { - return compareTo(JDK1_4_2) < 0; + return compareTo(JDK1_5) < 0; } /** Sometimes we need to create a field to cache a value like a - * class literal of the assertions flag. In -target 1.4.2 and + * class literal of the assertions flag. In -target 1.5 and * later we create a new synthetic class for this instead of * using the outermost class. See 4401576. */ public boolean useInnerCacheClass() { - return compareTo(JDK1_4_2) >= 0; + return compareTo(JDK1_5) >= 0; } /** Return true if cldc-style stack maps need to be generated. */ @@ -276,7 +265,7 @@ * See 4468823 */ public boolean classLiteralsNoInit() { - return compareTo(JDK1_4_2) >= 0; + return compareTo(JDK1_5) >= 0; } /** Although we may not have support for class literals, when we @@ -300,22 +289,10 @@ return compareTo(JDK1_5) >= 0; } - /** For bootstrapping javac only, we do without java.lang.Enum if - * necessary. - */ - public boolean compilerBootstrap(Symbol c) { - return - this == JSR14 && - (c.flags() & Flags.ENUM) != 0 && - c.flatName().toString().startsWith("com.sun.tools.") - // && !Target.class.getSuperclass().getName().equals("java.lang.Enum") - ; - } - /** In J2SE1.5.0, we introduced the "EnclosingMethod" attribute * for improved reflection support. */ public boolean hasEnclosingMethodAttribute() { - return compareTo(JDK1_5) >= 0 || this == JSR14; + return compareTo(JDK1_5) >= 0; } }
--- a/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -273,7 +273,7 @@ /** * ExceptionProxy for MirroredTypeException. - * The toString, hashCode, and equals methods foward to the underlying + * The toString, hashCode, and equals methods forward to the underlying * type. */ private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,412 @@ +/* + * 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 + * 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.model; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Kinds; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Type.AnnotatedType; +import com.sun.tools.javac.util.ListBuffer; +import static com.sun.tools.javac.code.TypeTag.CLASS; + +/** + * Utility methods for operating on annotated constructs. + * + * <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 JavacAnnoConstructs { + + // <editor-fold defaultstate="collapsed" desc="Symbols"> + + /** + * 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); + 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); + } + + // 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); + Attribute.Compound result = null; + while (annotated.name != annotated.name.table.names.java_lang_Object) { + result = getAttribute(annotated, annoType); + if (result != null || !inherited) + break; + Type sup = annotated.getSuperclass(); + if (!sup.hasTag(CLASS) || sup.isErroneous()) + break; + annotated = (ClassSymbol) sup.tsym; + } + 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; + } + + // </editor-fold> + + // <editor-fold defaultstate="collapsed" desc="Types"> + + /** + * An internal-use utility that creates a runtime view of an + * annotation. This is the implementation of + * TypeMirror.getAnnotation(Class). + */ + public static <A extends Annotation> A getAnnotation(AnnotatedType annotated, Class<A> annoType) { + if (!annoType.isAnnotation()) + throw new IllegalArgumentException("Not an annotation type: " + + annoType); + Attribute.Compound c = getAttribute(annotated, annoType); + return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); + } + + // Helper to getAnnotation[s] + private static <A extends Annotation> Attribute.Compound getAttribute(Type annotated, + Class<A> annoType) { + String name = annoType.getName(); + + for (Attribute.Compound anno : annotated.getAnnotationMirrors()) { + if (name.equals(anno.type.tsym.flatName().toString())) + return anno; + } + + return null; + } + + /** + * An internal-use utility that creates a runtime view of + * annotations. This is the implementation of + * TypeMirror.getAnnotationsByType(Class). + */ + public static <A extends Annotation> A[] getAnnotationsByType(AnnotatedType 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.getAnnotationMirrors().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]; + } + } + + // 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; + } + + // </editor-fold> + + // <editor-fold defaultstate="collapsed" desc="Container support"> + + // 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; + } + + // </editor-fold> +}
--- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Mar 25 18:08:47 2013 -0700 @@ -25,10 +25,6 @@ package com.sun.tools.javac.model; -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; @@ -40,7 +36,6 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; @@ -98,237 +93,6 @@ enter = Enter.instance(context); } - /** - * 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); - 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); - } - - // 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); - Attribute.Compound result = null; - while (annotated.name != annotated.name.table.names.java_lang_Object) { - result = getAttribute(annotated, annoType); - if (result != null || !inherited) - break; - Type sup = annotated.getSuperclass(); - if (!sup.hasTag(CLASS) || sup.isErroneous()) - break; - annotated = (ClassSymbol) sup.tsym; - } - 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(); if (strName.equals(""))
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Mar 25 18:08:47 2013 -0700 @@ -25,7 +25,6 @@ package com.sun.tools.javac.model; -import java.lang.annotation.Annotation; import java.util.Collections; import java.util.EnumSet; import java.util.LinkedHashSet; @@ -333,28 +332,4 @@ 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/src/share/classes/com/sun/tools/javac/sym/Profiles.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/sym/Profiles.java Mon Mar 25 18:08:47 2013 -0700 @@ -149,12 +149,13 @@ } final static Map<String, Package> packages = new TreeMap<String, Package>(); - int maxProfile; + + final int maxProfile = 4; // Three compact profiles plus full JRE MakefileProfiles(Properties p) { - int profile = 1; - while (true) { - String inclPackages = p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_PACKAGES"); + for (int profile = 1; profile <= maxProfile; profile++) { + String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE"); + String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES"); if (inclPackages == null) break; for (String pkg: inclPackages.substring(1).trim().split("\\s+")) { @@ -162,22 +163,20 @@ pkg = pkg.substring(0, pkg.length() - 1); includePackage(profile, pkg); } - String inclTypes = p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_TYPES"); + String inclTypes = p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES"); if (inclTypes != null) { for (String type: inclTypes.replace("$$", "$").split("\\s+")) { if (type.endsWith(".class")) includeType(profile, type.substring(0, type.length() - 6)); } } - String exclTypes = p.getProperty("PROFILE_" + profile + "_RTJAR_EXCLUDE_TYPES"); + String exclTypes = p.getProperty(prefix + "_RTJAR_EXCLUDE_TYPES"); if (exclTypes != null) { for (String type: exclTypes.replace("$$", "$").split("\\s+")) { if (type.endsWith(".class")) excludeType(profile, type.substring(0, type.length() - 6)); } } - maxProfile = profile; - profile++; } }
--- a/src/share/classes/com/sun/tools/javac/util/ArrayUtils.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/ArrayUtils.java Mon Mar 25 18:08:47 2013 -0700 @@ -85,17 +85,4 @@ } } - public static <T> T[] concat(T[] anArr, T[] anotherArr) { - int newLength = anArr.length + anotherArr.length; - @SuppressWarnings("unchecked") - T[] result = (T[]) Array.newInstance(anArr.getClass().getComponentType(), newLength); - System.arraycopy(anArr, 0, result, 0, anArr.length); - System.arraycopy(anotherArr, 0, result, anArr.length, anotherArr.length); - return result; - } - - @SuppressWarnings("unchecked") - public static <T> T[] concatOpen(T[] anArr, T... anotherArr) { - return concat(anArr, anotherArr); - } }
--- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Mon Mar 25 18:08:47 2013 -0700 @@ -509,6 +509,16 @@ visit(supertype); visit(interfaces); } + } else if (t.tsym.name.isEmpty()) { + //anon class + ClassType norm = (ClassType) t.tsym.type; + if (norm != null) { + if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) { + visit(norm.interfaces_field.head); + } else { + visit(norm.supertype_field); + } + } } nameSimplifier.addUsage(t.tsym); visit(t.getTypeArguments()); @@ -562,7 +572,7 @@ // <editor-fold defaultstate="collapsed" desc="symbol scanner"> /** * Preprocess a given symbol looking for (i) additional info (where clauses) to be - * asdded to the main diagnostic (ii) names to be compacted + * added to the main diagnostic (ii) names to be compacted */ protected void preprocessSymbol(Symbol s) { symbolPreprocessor.visit(s, null);
--- a/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java Mon Mar 25 18:08:47 2013 -0700 @@ -205,7 +205,7 @@ if (recvtype == null) { return new AnnotationDesc[0]; } - if (recvtype.getKind() != TypeKind.ANNOTATED) { + if (!recvtype.isAnnotated()) { return new AnnotationDesc[0]; } List<? extends Compound> typeAnnos = ((com.sun.tools.javac.code.Type.AnnotatedType)recvtype).typeAnnotations;
--- a/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Mon Mar 25 18:08:47 2013 -0700 @@ -65,11 +65,11 @@ t = env.types.erasure(t); } if (considerAnnotations - && t.getKind() == TypeKind.ANNOTATED) { + && t.isAnnotated()) { return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t); } - if (t.getKind() == TypeKind.ANNOTATED) { + if (t.isAnnotated()) { Type.AnnotatedType at = (Type.AnnotatedType) t; return new AnnotatedTypeImpl(env, at); } @@ -147,7 +147,7 @@ */ static String getTypeString(DocEnv env, Type t, boolean full) { // TODO: should annotations be included here? - if (t.getKind() == TypeKind.ANNOTATED) { + if (t.isAnnotated()) { Type.AnnotatedType at = (Type.AnnotatedType)t; t = at.underlyingType; }
--- a/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Mon Mar 25 18:08:47 2013 -0700 @@ -127,7 +127,7 @@ final Type upperBound = v.getUpperBound(); Name boundname = upperBound.tsym.getQualifiedName(); if (boundname == boundname.table.names.java_lang_Object - && upperBound.getKind() != TypeKind.ANNOTATED) { + && !upperBound.isAnnotated()) { return List.nil(); } else { return env.types.getBounds(v); @@ -139,7 +139,7 @@ * Return an empty array if there are none. */ public AnnotationDesc[] annotations() { - if (type.getKind() != TypeKind.ANNOTATED) { + if (!type.isAnnotated()) { return new AnnotationDesc[0]; } List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations;
--- a/src/share/classes/com/sun/tools/javah/Util.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javah/Util.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, 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 @@ -144,10 +144,6 @@ throw new Exit(15); } - private void fatal(String msg) throws Exit { - fatal(msg, null); - } - private void fatal(String msg, Exception e) throws Exit { dl.report(createDiagnostic(Diagnostic.Kind.ERROR, "", msg)); throw new Exit(10, e);
--- a/src/share/classes/com/sun/tools/javap/StackMapWriter.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/javap/StackMapWriter.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -269,7 +269,7 @@ } - class StackMap { + static class StackMap { StackMap(verification_type_info[] locals, verification_type_info[] stack) { this.locals = locals; this.stack = stack; @@ -279,7 +279,7 @@ private final verification_type_info[] stack; } - class CustomVerificationTypeInfo extends verification_type_info { + static class CustomVerificationTypeInfo extends verification_type_info { public CustomVerificationTypeInfo(String text) { super(-1); this.text = text;
--- a/src/share/classes/com/sun/tools/jdeps/Analyzer.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/jdeps/Analyzer.java Mon Mar 25 18:08:47 2013 -0700 @@ -91,9 +91,11 @@ result.requiredArchives.add(source); } // either a profile name or the archive name - String tname = getProfile(target); - if (tname.isEmpty()){ - tname = source.toString(); + String tname = result.getTargetProfile(target); + if (tname.isEmpty()) { + tname = PlatformClassPath.contains(source) + ? "JDK internal API (" + source.getFileName() + ")" + : source.toString(); } if (!result.targetNames.contains(tname)) { result.targetNames.add(tname); @@ -110,7 +112,7 @@ * a fully-qualified classname, a package name, a profile or * archive name depending on the Analyzer's type. */ - void visit(String origin, String target); + void visit(String origin, String target, String profile); /** * Visits the source archive to its destination archive of * a recorded dependency. @@ -124,7 +126,7 @@ v.visit(r.archive, a); } for (String name : r.targetNames) { - v.visit(r.archive.getFileName(), name); + v.visit(r.archive.getFileName(), name, name); } } } @@ -138,7 +140,7 @@ for (String target : r.deps.get(origin)) { // filter intra-dependency unless in verbose mode if (type == Type.VERBOSE || getArchive(origin) != getArchive(target)) { - v.visit(origin, target); + v.visit(origin, target, r.getTargetProfile(target)); } } } @@ -149,21 +151,16 @@ return map.containsKey(name) ? map.get(name) : NOT_FOUND; } - public String getArchiveName(String name) { - return getArchive(name).getFileName(); - } - - public String getProfile(String name) { - String pn = type == Type.CLASS ? packageOf(name) : name; - Archive source = map.get(name); - if (source != null && PlatformClassPath.contains(source)) { - String profile = PlatformClassPath.getProfileName(pn); - if (profile.isEmpty()) { - return "JDK internal API (" + source.getFileName() + ")"; - } - return profile; - } - return ""; + /** + * Returns the file name of the archive for non-JRE class or + * internal JRE classes. It returns empty string for SE API. + */ + public String getArchiveName(String target, String profile) { + Archive source = getArchive(target); + String name = source.getFileName(); + if (PlatformClassPath.contains(source)) + return profile.isEmpty() ? "JDK internal API (" + name + ")" : ""; + return name; } private abstract class ArchiveDeps implements Archive.Visitor { @@ -200,6 +197,8 @@ } public abstract void visit(Location o, Location t); + public abstract String getTargetProfile(String target); + } private class ClassVisitor extends ArchiveDeps { @@ -212,6 +211,10 @@ public void visit(Location o, Location t) { add(o.getClassName(), t.getClassName()); } + public String getTargetProfile(String target) { + int i = target.lastIndexOf('.'); + return (i > 0) ? Profiles.getProfileName(target.substring(0, i)) : ""; + } } private class PackageVisitor extends ArchiveDeps { @@ -221,19 +224,15 @@ public void visit(Location o, Location t) { add(packageOf(o), packageOf(t)); } - public void visit(Location l) { add(packageOf(l)); } - private String packageOf(Location loc) { String pkg = loc.getPackageName(); return pkg.isEmpty() ? "<unnamed>" : pkg; } - } - - private static String packageOf(String cn) { - int i = cn.lastIndexOf('.'); - return (i > 0) ? cn.substring(0, i) : "<unnamed>"; + public String getTargetProfile(String target) { + return Profiles.getProfileName(target); + } } }
--- a/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Mon Mar 25 18:08:47 2013 -0700 @@ -59,6 +59,13 @@ } } + /** + * Returns a ClassFileReader instance of a given JarFile. + */ + public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException { + return new JarFileReader(path, jf); + } + protected final Path path; protected final String baseFileName; private ClassFileReader(Path path) { @@ -228,8 +235,11 @@ private static class JarFileReader extends ClassFileReader { final JarFile jarfile; JarFileReader(Path path) throws IOException { + this(path, new JarFile(path.toFile())); + } + JarFileReader(Path path, JarFile jf) throws IOException { super(path); - this.jarfile = new JarFile(path.toFile()); + this.jarfile = jf; } public ClassFile getClassFile(String name) throws IOException {
--- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * Implementation for the jdeps tool for static class dependency analysis. */ class JdepsTask { - class BadArgs extends Exception { + static class BadArgs extends Exception { static final long serialVersionUID = 8765093759964640721L; BadArgs(String key, Object... args) { super(JdepsTask.getMessage(key, args)); @@ -119,7 +119,7 @@ } else if ("class".equals(arg)) { task.options.verbose = Analyzer.Type.CLASS; } else { - throw task.new BadArgs("err.invalid.arg.for.option", opt); + throw new BadArgs("err.invalid.arg.for.option", opt); } } }, @@ -139,8 +139,11 @@ } }, new Option(false, "-P", "--profile") { - void process(JdepsTask task, String opt, String arg) { + void process(JdepsTask task, String opt, String arg) throws BadArgs { task.options.showProfile = true; + if (Profiles.getProfileCount() == 0) { + throw new BadArgs("err.option.unsupported", opt, getMessage("err.profiles.msg")); + } } }, new Option(false, "-R", "--recursive") { @@ -153,7 +156,7 @@ try { task.options.depth = Integer.parseInt(arg); } catch (NumberFormatException e) { - throw task.new BadArgs("err.invalid.arg.for.option", opt); + throw new BadArgs("err.invalid.arg.for.option", opt); } } }, @@ -382,9 +385,9 @@ private void printSummary(final PrintWriter out, final Analyzer analyzer) { Analyzer.Visitor visitor = new Analyzer.Visitor() { - public void visit(String origin, String profile) { + public void visit(String origin, String target, String profile) { if (options.showProfile) { - out.format("%-30s -> %s%n", origin, profile); + out.format("%-30s -> %s%n", origin, target); } } public void visit(Archive origin, Archive target) { @@ -399,17 +402,15 @@ private void printDependencies(final PrintWriter out, final Analyzer analyzer) { Analyzer.Visitor visitor = new Analyzer.Visitor() { private String pkg = ""; - public void visit(String origin, String target) { + public void visit(String origin, String target, String profile) { if (!origin.equals(pkg)) { pkg = origin; - out.format(" %s (%s)%n", origin, analyzer.getArchiveName(origin)); + out.format(" %s (%s)%n", origin, analyzer.getArchive(origin).getFileName()); } - Archive source = analyzer.getArchive(target); - String profile = options.showProfile ? analyzer.getProfile(target) : ""; out.format(" -> %-50s %s%n", target, - PlatformClassPath.contains(source) + (options.showProfile && !profile.isEmpty()) ? profile - : analyzer.getArchiveName(target)); + : analyzer.getArchiveName(target, profile)); } public void visit(Archive origin, Archive target) { out.format("%s -> %s%n", origin, target); @@ -514,7 +515,6 @@ boolean help; boolean version; boolean fullVersion; - boolean showFlags; boolean showProfile; boolean showSummary; boolean wildcard;
--- a/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,34 +37,6 @@ * ClassPath for Java SE and JDK */ class PlatformClassPath { - /* - * Profiles for Java SE - * - * This is a temporary workaround until a common API is defined for langtools - * to determine which profile a given classname belongs to. The list of - * packages and profile names are hardcoded in jdk.properties and - * split packages are not supported. - */ - static class Profile { - final String name; - final Set<String> packages; - - Profile(String name) { - this.name = name; - this.packages = new HashSet<String>(); - } - } - - private final static String JAVAFX = "javafx"; - private final static Map<String,Profile> map = getProfilePackages(); - static String getProfileName(String packageName) { - Profile profile = map.get(packageName); - if (packageName.startsWith(JAVAFX + ".")) { - profile = map.get(JAVAFX); - } - return profile != null ? profile.name : ""; - } - private final static List<Archive> javaHomeArchives = init(); static List<Archive> getArchives() { return javaHomeArchives; @@ -77,7 +49,6 @@ private static List<Archive> init() { List<Archive> result = new ArrayList<Archive>(); String javaHome = System.getProperty("java.home"); - List<File> files = new ArrayList<File>(); File jre = new File(javaHome, "jre"); File lib = new File(javaHome, "lib"); @@ -100,13 +71,6 @@ } catch (IOException e) { throw new RuntimeException(e); } - - // add a JavaFX profile if there is jfxrt.jar - for (Archive archive : result) { - if (archive.getFileName().equals("jfxrt.jar")) { - map.put(JAVAFX, new Profile("jfxrt.jar")); - } - } return result; } @@ -140,30 +104,4 @@ }); return result; } - - private static Map<String,Profile> getProfilePackages() { - Map<String,Profile> map = new HashMap<String,Profile>(); - - // read the properties as a ResourceBundle as the build compiles - // the properties file into Java class. Another alternative is - // to load it as Properties and fix the build to exclude this file. - ResourceBundle profileBundle = - ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk"); - - int i=1; - String key; - while (profileBundle.containsKey((key = "profile." + i + ".name"))) { - Profile profile = new Profile(profileBundle.getString(key)); - String n = profileBundle.getString("profile." + i + ".packages"); - String[] pkgs = n.split("\\s+"); - for (String p : pkgs) { - if (p.isEmpty()) continue; - assert(map.containsKey(p) == false); - profile.packages.add(p); - map.put(p, profile); - } - i++; - } - return map; - } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/jdeps/Profiles.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,241 @@ +/* + * 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. 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.jdeps; + +import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.Annotation.*; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.RuntimeAnnotations_attribute; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.jar.JarFile; + +/** + * Build the profile information from ct.sym if exists. + */ +class Profiles { + private static final Map<String,Profile> map = initProfiles(); + /** + * Returns the name of the profile for the given package name. + * It returns an empty string if the given package is not in any profile. + */ + public static String getProfileName(String pn) { + Profile profile = map.get(pn); + return (profile != null && profile.packages.contains(pn)) + ? profile.name : ""; + } + + public static int getProfileCount() { + return new HashSet<Profile>(map.values()).size(); + } + + private static Map<String,Profile> initProfiles() { + List<Profile> profiles = new ArrayList<Profile>(); + try { + String profilesProps = System.getProperty("jdeps.profiles"); + if (profilesProps != null) { + // for testing for JDK development build where ct.sym doesn't exist + initProfilesFromProperties(profiles, profilesProps); + } else { + Path home = Paths.get(System.getProperty("java.home")); + if (home.endsWith("jre")) { + home = home.getParent(); + } + Path ctsym = home.resolve("lib").resolve("ct.sym"); + if (ctsym.toFile().exists()) { + // add a default Full JRE + profiles.add(0, new Profile("Full JRE", 0)); + // parse ct.sym and load information about profiles + try (JarFile jf = new JarFile(ctsym.toFile())) { + ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf); + for (ClassFile cf : reader.getClassFiles()) { + findProfile(profiles, cf); + } + } + + // merge the last Profile with the "Full JRE" + if (profiles.size() > 1) { + Profile fullJRE = profiles.get(0); + Profile p = profiles.remove(profiles.size() - 1); + for (String pn : fullJRE.packages) { + // The last profile contains the packages determined from ct.sym. + // Move classes annotated profile==0 or no attribute that are + // added in the fullJRE profile to either supported or proprietary + // packages appropriately + if (p.proprietaryPkgs.contains(pn)) { + p.proprietaryPkgs.add(pn); + } else { + p.packages.add(pn); + } + } + fullJRE.packages.clear(); + fullJRE.proprietaryPkgs.clear(); + fullJRE.packages.addAll(p.packages); + fullJRE.proprietaryPkgs.addAll(p.proprietaryPkgs); + } + } + } + } catch (IOException | ConstantPoolException e) { + throw new Error(e); + } + HashMap<String,Profile> map = new HashMap<String,Profile>(); + for (Profile profile : profiles) { + // Inner classes are not annotated with the profile annotation + // packages may be in one profile but also appear in the Full JRE + // Full JRE is always the first element in profiles list and + // so the map will contain the appropriate Profile + for (String pn : profile.packages) { + map.put(pn, profile); + } + for (String pn : profile.proprietaryPkgs) { + map.put(pn, profile); + } + } + return map; + } + + private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;"; + private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;"; + private static Profile findProfile(List<Profile> profiles, ClassFile cf) + throws ConstantPoolException + { + RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute) + cf.attributes.get(Attribute.RuntimeInvisibleAnnotations); + int index = 0; + boolean proprietary = false; + if (attr != null) { + for (int i = 0; i < attr.annotations.length; i++) { + Annotation ann = attr.annotations[i]; + String annType = cf.constant_pool.getUTF8Value(ann.type_index); + if (PROFILE_ANNOTATION.equals(annType)) { + for (int j = 0; j < ann.num_element_value_pairs; j++) { + Annotation.element_value_pair pair = ann.element_value_pairs[j]; + Primitive_element_value ev = (Primitive_element_value)pair.value; + CONSTANT_Integer_info info = (CONSTANT_Integer_info) + cf.constant_pool.get(ev.const_value_index); + index = info.value; + break; + } + } else if (PROPRIETARY_ANNOTATION.equals(annType)) { + proprietary = true; + } + } + if (index >= profiles.size()) { + Profile p = null; + for (int i = profiles.size(); i <= index; i++) { + p = new Profile(i); + profiles.add(p); + } + } + } + + Profile p = profiles.get(index); + String name = cf.getName(); + int i = name.lastIndexOf('/'); + name = (i > 0) ? name.substring(0, i).replace('/','.') : ""; + if (proprietary) { + p.proprietaryPkgs.add(name); + } else { + p.packages.add(name); + } + return p; + } + + private static void initProfilesFromProperties(List<Profile> profiles, String path) + throws IOException + { + Properties props = new Properties(); + try (FileReader reader = new FileReader(path)) { + props.load(reader); + } + int i=1; + String key; + while (props.containsKey((key = "profile." + i + ".name"))) { + Profile profile = new Profile(props.getProperty(key), i); + profiles.add(profile); + String n = props.getProperty("profile." + i + ".packages"); + String[] pkgs = n.split("\\s+"); + for (String p : pkgs) { + if (p.isEmpty()) continue; + profile.packages.add(p); + } + i++; + } + } + + private static class Profile { + final String name; + final int profile; + final Set<String> packages; + final Set<String> proprietaryPkgs; + Profile(int profile) { + this("compact" + profile, profile); + } + Profile(String name, int profile) { + this.name = name; + this.profile = profile; + this.packages = new HashSet<String>(); + this.proprietaryPkgs = new HashSet<String>(); + } + public String toString() { + return name; + } + } + + // for debugging + public static void main(String[] args) { + if (args.length == 0) { + Profile[] profiles = new Profile[getProfileCount()]; + for (Profile p : map.values()) { + // move the zeroth profile to the last + int index = p.profile == 0 ? profiles.length-1 : p.profile-1; + profiles[index] = p; + } + for (Profile p : profiles) { + String profileName = p.name; + SortedSet<String> set = new TreeSet<String>(p.packages); + for (String s : set) { + // filter out the inner classes that are not annotated with + // the profile annotation + if (map.get(s) == p) { + System.out.format("%-10s %s%n", profileName, s); + profileName = ""; + } + } + } + } + for (String pn : args) { + System.out.format("%s in %s%n", pn, getProfileName(pn)); + } + } +}
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Mon Mar 25 18:08:47 2013 -0700 @@ -51,6 +51,8 @@ err.internal.error=internal error: {0} {1} {2} err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} +err.option.unsupported={0} not supported: {1} +err.profiles.msg=No profile information warn.invalid.arg=Invalid classname or pathname not exist: {0} warn.split.package=package {0} defined in {1} {2}
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdk.properties Mon Mar 25 16:55:14 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,262 +0,0 @@ -# This properties file does not need localization. - -profile.1.name = compact1 -profile.1.packages = \ - java.io \ - java.lang \ - java.lang.annotation \ - java.lang.invoke \ - java.lang.ref \ - java.lang.reflect \ - java.math \ - java.net \ - java.nio \ - java.nio.channels \ - java.nio.channels.spi \ - java.nio.charset \ - java.nio.charset.spi \ - java.nio.file \ - java.nio.file.attribute \ - java.nio.file.spi \ - java.security \ - java.security.cert \ - java.security.interfaces \ - java.security.spec \ - java.text \ - java.text.spi \ - java.util \ - java.util.concurrent \ - java.util.concurrent.atomic \ - java.util.concurrent.locks \ - java.util.jar \ - java.util.logging \ - java.util.regex \ - java.util.spi \ - java.util.zip \ - javax.crypto \ - javax.crypto.interfaces \ - javax.crypto.spec \ - javax.security.auth \ - javax.security.auth.callback \ - javax.security.auth.login \ - javax.security.auth.spi \ - javax.security.auth.x500 \ - javax.net \ - javax.net.ssl \ - javax.security.cert \ - \ - com.sun.net.ssl \ - com.sun.nio.file \ - com.sun.nio.sctp \ - com.sun.security.auth \ - com.sun.security.auth.login - -profile.2.name = compact2 -profile.2.packages = \ - java.sql \ - javax.sql \ - javax.xml \ - javax.xml.datatype \ - javax.xml.namespace \ - javax.xml.parsers \ - javax.xml.stream \ - javax.xml.stream.events \ - javax.xml.stream.util \ - javax.xml.transform \ - javax.xml.transform.dom \ - javax.xml.transform.sax \ - javax.xml.transform.stax \ - javax.xml.transform.stream \ - javax.xml.validation \ - javax.xml.xpath \ - org.w3c.dom \ - org.w3c.dom.bootstrap \ - org.w3c.dom.events \ - org.w3c.dom.ls \ - org.xml.sax \ - org.xml.sax.ext \ - org.xml.sax.helpers \ - java.rmi \ - java.rmi.activation \ - java.rmi.dgc \ - java.rmi.registry \ - java.rmi.server \ - javax.rmi.ssl \ - javax.transaction \ - javax.transaction.xa \ - \ - com.sun.net.httpserver \ - com.sun.net.httpserver.spi - -profile.3.name = compact3 -profile.3.packages = \ - java.lang.instrument \ - java.lang.management \ - java.security.acl \ - java.util.prefs \ - javax.management \ - javax.management.loading \ - javax.management.modelmbean \ - javax.management.monitor \ - javax.management.openmbean \ - javax.management.relation \ - javax.management.remote \ - javax.management.remote.rmi \ - javax.management.timer \ - javax.naming \ - javax.naming.directory \ - javax.naming.event \ - javax.naming.ldap \ - javax.naming.spi \ - javax.sql.rowset \ - javax.sql.rowset.serial \ - javax.sql.rowset.spi \ - javax.security.auth.kerberos \ - javax.security.sasl \ - javax.script \ - javax.smartcardio \ - javax.xml.crypto \ - javax.xml.crypto.dom \ - javax.xml.crypto.dsig \ - javax.xml.crypto.dsig.dom \ - javax.xml.crypto.dsig.keyinfo \ - javax.xml.crypto.dsig.spec \ - javax.annotation.processing \ - javax.lang.model \ - javax.lang.model.element \ - javax.lang.model.type \ - javax.lang.model.util \ - javax.tools \ - javax.tools.annotation \ - org.ietf.jgss \ - \ - com.sun.management \ - com.sun.security.auth.callback \ - com.sun.security.auth.module \ - com.sun.security.jgss - -profile.4.name = Full JRE -profile.4.packages = \ - java.applet \ - java.awt \ - java.awt.color \ - java.awt.datatransfer \ - java.awt.dnd \ - java.awt.dnd.peer \ - java.awt.event \ - java.awt.font \ - java.awt.geom \ - java.awt.im \ - java.awt.im.spi \ - java.awt.image \ - java.awt.image.renderable \ - java.awt.peer \ - java.awt.print \ - java.beans \ - java.beans.beancontext \ - javax.accessibility \ - javax.imageio \ - javax.imageio.event \ - javax.imageio.metadata \ - javax.imageio.plugins.bmp \ - javax.imageio.plugins.jpeg \ - javax.imageio.spi \ - javax.imageio.stream \ - javax.print \ - javax.print.attribute \ - javax.print.attribute.standard \ - javax.print.event \ - javax.sound.midi \ - javax.sound.midi.spi \ - javax.sound.sampled \ - javax.sound.sampled.spi \ - javax.swing \ - javax.swing.border \ - javax.swing.colorchooser \ - javax.swing.event \ - javax.swing.filechooser \ - javax.swing.plaf \ - javax.swing.plaf.basic \ - javax.swing.plaf.metal \ - javax.swing.plaf.multi \ - javax.swing.plaf.nimbus \ - javax.swing.plaf.synth \ - javax.swing.table \ - javax.swing.text \ - javax.swing.text.html \ - javax.swing.text.html.parser \ - javax.swing.text.rtf \ - javax.swing.tree \ - javax.swing.undo \ - javax.activation \ - javax.jws \ - javax.jws.soap \ - javax.rmi \ - javax.rmi.CORBA \ - javax.xml.bind \ - javax.xml.bind.annotation \ - javax.xml.bind.annotation.adapters \ - javax.xml.bind.attachment \ - javax.xml.bind.helpers \ - javax.xml.bind.util \ - javax.xml.soap \ - javax.xml.ws \ - javax.xml.ws.handler \ - javax.xml.ws.handler.soap \ - javax.xml.ws.http \ - javax.xml.ws.soap \ - javax.xml.ws.spi \ - javax.xml.ws.spi.http \ - javax.xml.ws.wsaddressing \ - javax.annotation \ - org.omg.CORBA \ - org.omg.CORBA.DynAnyPackage \ - org.omg.CORBA.ORBPackage \ - org.omg.CORBA.TypeCodePackage \ - org.omg.CORBA.portable \ - org.omg.CORBA_2_3 \ - org.omg.CORBA_2_3.portable \ - org.omg.CosNaming \ - org.omg.CosNaming.NamingContextExtPackage \ - org.omg.CosNaming.NamingContextPackage \ - org.omg.Dynamic \ - org.omg.DynamicAny \ - org.omg.DynamicAny.DynAnyFactoryPackage \ - org.omg.DynamicAny.DynAnyPackage \ - org.omg.IOP \ - org.omg.IOP.CodecFactoryPackage \ - org.omg.IOP.CodecPackage \ - org.omg.Messaging \ - org.omg.PortableInterceptor \ - org.omg.PortableInterceptor.ORBInitInfoPackage \ - org.omg.PortableServer \ - org.omg.PortableServer.CurrentPackage \ - org.omg.PortableServer.POAManagerPackage \ - org.omg.PortableServer.POAPackage \ - org.omg.PortableServer.ServantLocatorPackage \ - org.omg.PortableServer.portable \ - org.omg.SendingContext \ - org.omg.stub.java.rmi \ - org.omg.stub.javax.management.remote.rmi - -# Remaining JDK supported API -profile.5.name = JDK tools -profile.5.packages = \ - com.sun.jdi \ - com.sun.jdi.connect \ - com.sun.jdi.connect.spi \ - com.sun.jdi.event \ - com.sun.jdi.request \ - com.sun.javadoc \ - com.sun.tools.doclets \ - com.sun.tools.doctree \ - com.sun.source.tree \ - com.sun.source.util \ - com.sun.tools.attach \ - com.sun.tools.attach.spi \ - com.sun.tools.jconsole \ - com.sun.tools.javac \ - com.sun.tools.javah \ - com.sun.tools.javap \ - com.sun.tools.javadoc \ - com.sun.servicetag
--- a/src/share/classes/com/sun/tools/sjavac/Main.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/sjavac/Main.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,13 @@ 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.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.sun.tools.sjavac.server.JavacServer; /** * The main class of the smart javac wrapper tool. @@ -268,12 +263,12 @@ // 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>(); +// 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); +// 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); @@ -935,13 +930,13 @@ if (roots.contains(root)) { throw new ProblemException("\""+r+"\" has already been used for "+option); } - if (roots.equals(bin_dir)) { + if (root.equals(bin_dir)) { throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d"); } - if (roots.equals(gensrc_dir)) { + if (root.equals(gensrc_dir)) { throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s"); } - if (roots.equals(header_dir)) { + if (root.equals(header_dir)) { throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h"); } roots.add(root);
--- a/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Mon Mar 25 18:08:47 2013 -0700 @@ -108,7 +108,7 @@ return new_deps; } - class CompareNames implements Comparator<Name> { + static class CompareNames implements Comparator<Name> { public int compare(Name a, Name b) { return a.toString().compareTo(b.toString()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/lang/model/AnnotatedConstruct.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,190 @@ +/* + * 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. 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; + +import java.lang.annotation.*; +import java.util.List; +import javax.lang.model.element.*; +import javax.lang.model.type.*; + +/** + * Represents a construct that can be annotated. + * + * A construct is either an {@linkplain + * javax.lang.model.element.Element element} or a {@linkplain + * javax.lang.model.type.TypeMirror type}. Annotations on an element + * are on a <em>declaration</em>, whereas annotations on a type are on + * a specific <em>use</em> of a type name. + * + * The terms <em>directly present</em> and <em>present</em> are used + * throughout this interface to describe precisely which annotations + * are returned by methods: + * + * <p>An annotation <i>A</i> is <em>directly present</em> on a + * construct <i>E</i> if <i>E</i> is annotated, and: + * + * <ul> + * + * <li> for an invocation of {@code getAnnotation(Class<T>)} or + * {@code getAnnotationMirrors()}, <i>E</i>'s annotations contain <i>A</i>. + * + * <li> for an invocation of getAnnotationsByType(Class<T>), + * <i>E</i>'s annotations either contain <i>A</i> or, if the type of + * <i>A</i> is repeatable, contain exactly one annotation whose value + * element contains <i>A</i> and whose type is the containing + * annotation type of <i>A</i>'s type. + * + * </ul> + * + * <p>An annotation A is <em>present</em> on a construct E if either: + * + * <ul> + * <li> <i>A</i> is <em>directly present</em> on <i>E</i>; or + * + * <li> <i>A</i> is not <em>directly present</em> on <i>E</i>, and + * <i>E</i> is an element representing a class, and <i>A</i>'s type + * is inheritable, and <i>A</i> is <em>present</em> on the element + * representing the superclass of <i>E</i>. + * + * </ul> + * + * @since 1.8 + * @jls 9.6 Annotation Types + * @jls 9.6.3.3 @Inherited + */ +public interface AnnotatedConstruct { + /** + * Returns the annotations that are <em>directly present</em> on + * this construct. + * + * @return the annotations <em>directly present</em> on this + * construct; an empty list if there are none + */ + List<? extends AnnotationMirror> getAnnotationMirrors(); + + /** + * Returns this construct's annotation of the + * specified type if such an annotation is <em>present</em>, else {@code + * null}. + * + * <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 annotationType the {@code Class} object corresponding to + * the annotation type + * @return this element's or type use's annotation for the + * specified annotation type if present on this element, else + * {@code null} + * + * @see #getAnnotationMirrors() + * @see java.lang.reflect.AnnotatedElement#getAnnotation + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + * @jls 9.6.1 Annotation Type Elements + */ + <A extends Annotation> A getAnnotation(Class<A> annotationType); + + /** + * Returns annotations that are <em>present</em> on this construct. + * + * If there are no annotations <em>present</em> on this construct, + * the return value is an array of length 0. + * + * The difference between this method and {@link #getAnnotation(Class)} + * is that this method detects if its argument is a <em>repeatable + * annotation type</em>, and if so, attempts to find one or more + * annotations of that type by "looking through" a container annotation. + * + * <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#getAnnotationsByType + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + * @jls 9.6 Annotation Types + * @jls 9.6.1 Annotation Type Elements + */ + <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType); +}
--- a/src/share/classes/javax/lang/model/element/Element.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/element/Element.java Mon Mar 25 18:08:47 2013 -0700 @@ -60,8 +60,7 @@ * @see TypeMirror * @since 1.6 */ -public interface Element { - +public interface Element extends javax.lang.model.AnnotatedConstruct { /** * Returns the type defined by this element. * @@ -89,119 +88,6 @@ ElementKind getKind(); /** - * Returns the annotations that are directly present on this element. - * - * <p> To get inherited annotations as well, use - * {@link Elements#getAllAnnotationMirrors(Element) getAllAnnotationMirrors}. - * - * @see ElementFilter - * - * @return the annotations directly present on this element; - * an empty list if there are none - */ - List<? extends AnnotationMirror> getAnnotationMirrors(); - - /** - * Returns this element's annotation for the specified type if - * such an annotation is present, else {@code null}. The - * annotation may be either inherited or 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 annotationType the {@code Class} object corresponding to - * the annotation type - * @return this element's annotation for the specified annotation - * type if present on this element, else {@code null} - * - * @see #getAnnotationMirrors() - * @see java.lang.reflect.AnnotatedElement#getAnnotation - * @see EnumConstantNotPresentException - * @see AnnotationTypeMismatchException - * @see IncompleteAnnotationException - * @see MirroredTypeException - * @see MirroredTypesException - */ - <A extends Annotation> A getAnnotation(Class<A> annotationType); - - /** - * Returns annotations that are <em>present</em> on this element. - * - * If there are no annotations <em>present</em> on this element, the return - * value is an array of length 0. - * - * The difference between this method and {@link #getAnnotation(Class)} - * is that this method detects if its argument is a <em>repeatable - * annotation type</em> (JLS 9.6), and if so, attempts to find one or more - * annotations of that type by "looking through" a container annotation. - * - * <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#getAnnotationsByType - * @see EnumConstantNotPresentException - * @see AnnotationTypeMismatchException - * @see IncompleteAnnotationException - * @see MirroredTypeException - * @see MirroredTypesException - */ - <A extends Annotation> A[] getAnnotationsByType(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. @@ -325,6 +211,19 @@ */ int hashCode(); + + /** + * {@inheritDoc} + * + * <p> To get inherited annotations as well, use {@link + * Elements#getAllAnnotationMirrors(Element) + * getAllAnnotationMirrors}. + * + * @see ElementFilter + * @since 1.6 + */ + @Override + List<? extends AnnotationMirror> getAnnotationMirrors(); /** * Applies a visitor to this element. *
--- a/src/share/classes/javax/lang/model/element/ExecutableElement.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/element/ExecutableElement.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -69,6 +69,25 @@ List<? extends VariableElement> getParameters(); /** + * Returns the receiver type of this executable, + * or {@link javax.lang.model.type.NoType NoType} with + * kind {@link javax.lang.model.type.TypeKind#NONE NONE} + * if the executable has no receiver type. + * + * An executable which is an instance method, or a constructor of an + * inner class, has a receiver type derived from the {@linkplain + * #getEnclosingElement declaring type}. + * + * An executable which is a static method, or a constructor of a + * non-inner class, or an initializer (static or instance), has no + * receiver type. + * + * @return the receiver type of this executable + * @since 1.8 + */ + TypeMirror getReceiverType(); + + /** * Returns {@code true} if this method or constructor accepts a variable * number of arguments and returns {@code false} otherwise. *
--- a/src/share/classes/javax/lang/model/type/AnnotatedType.java Mon Mar 25 16:55:14 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * 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/src/share/classes/javax/lang/model/type/ExecutableType.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/type/ExecutableType.java Mon Mar 25 18:08:47 2013 -0700 @@ -30,7 +30,6 @@ import javax.lang.model.element.ExecutableElement; - /** * Represents the type of an executable. An <i>executable</i> * is a method, constructor, or initializer. @@ -78,10 +77,21 @@ List<? extends TypeMirror> getParameterTypes(); /** - * Returns the type of this executable's receiver parameter. + * Returns the receiver type of this executable, + * or {@link javax.lang.model.type.NoType NoType} with + * kind {@link javax.lang.model.type.TypeKind#NONE NONE} + * if the executable has no receiver type. * - * @return the type of this executable's receiver parameter - * TODO: null if none specified or always a valid value? + * An executable which is an instance method, or a constructor of an + * inner class, has a receiver type derived from the {@linkplain + * ExecutableElement#getEnclosingElement declaring type}. + * + * An executable which is a static method, or a constructor of a + * non-inner class, or an initializer (static or instance), has no + * receiver type. + * + * @return the receiver type of this executable + * @since 1.8 */ TypeMirror getReceiverType();
--- a/src/share/classes/javax/lang/model/type/TypeKind.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/type/TypeKind.java Mon Mar 25 18:08:47 2013 -0700 @@ -151,14 +151,7 @@ * * @since 1.8 */ - INTERSECTION, - - /** - * An annotated type. - * - * @since 1.8 - */ - ANNOTATED; + INTERSECTION; /** * Returns {@code true} if this kind corresponds to a primitive
--- a/src/share/classes/javax/lang/model/type/TypeMirror.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/type/TypeMirror.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -25,6 +25,8 @@ package javax.lang.model.type; +import java.lang.annotation.Annotation; +import java.util.List; import javax.lang.model.element.*; import javax.lang.model.util.Types; @@ -55,7 +57,7 @@ * @see Types * @since 1.6 */ -public interface TypeMirror { +public interface TypeMirror extends javax.lang.model.AnnotatedConstruct { /** * Returns the {@code kind} of this type.
--- a/src/share/classes/javax/lang/model/type/TypeVisitor.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/type/TypeVisitor.java Mon Mar 25 18:08:47 2013 -0700 @@ -194,14 +194,4 @@ * @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/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Mon Mar 25 18:08:47 2013 -0700 @@ -134,23 +134,6 @@ } /** - * 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/src/share/classes/javax/lang/model/util/Types.java Mon Mar 25 16:55:14 2013 -0700 +++ b/src/share/classes/javax/lang/model/util/Types.java Mon Mar 25 18:08:47 2013 -0700 @@ -59,6 +59,13 @@ /** * Tests whether two {@code TypeMirror} objects represent the same type. * + * <p>Since annotations are only meta-data associated with a type, + * the set of annotations on either argument is <em>not</em> taken + * into account when computing whether or not two {@code + * TypeMirror} objects are the same type. In particular, two + * {@code TypeMirror} objects can have different annotations and + * still be considered the same. + * * <p>Caveat: if either of the arguments to this method represents a * wildcard, this method will return false. As a consequence, a wildcard * is not the same type as itself. This might be surprising at first, @@ -301,116 +308,4 @@ * 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/test/com/sun/javadoc/testProfiles/TestProfiles.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/com/sun/javadoc/testProfiles/TestProfiles.java Mon Mar 25 18:08:47 2013 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 8006124 + * @bug 8006124 8009684 * @summary Test javadoc support for profiles. * @author Bhavesh Patel * @library ../lib/ @@ -33,7 +33,7 @@ public class TestProfiles extends JavadocTester { //Test information. - private static final String BUG_ID = "8006124"; + private static final String BUG_ID = "8006124-8009684"; private static final String PROFILE_BUG_ID = BUG_ID + "-1"; private static final String PACKAGE_BUG_ID = BUG_ID + "-2"; //Javadoc arguments. @@ -49,17 +49,17 @@ // Tests for profile-overview-frame.html listing all profiles. {PROFILE_BUG_ID + FS + "profile-overview-frame.html", "<span><a href=\"overview-frame.html\" " - + "target=\"profileListFrame\">All Packages</a></span>" + + "target=\"packageListFrame\">All Packages</a></span>" }, {PROFILE_BUG_ID + FS + "profile-overview-frame.html", - "<li><a href=\"compact1-frame.html\" target=\"profileListFrame\">" + "<li><a href=\"compact1-frame.html\" target=\"packageListFrame\">" + "compact1</a></li>" }, // Tests for profileName-frame.html listing all packages in a profile. {PROFILE_BUG_ID + FS + "compact2-frame.html", - "<span><a href=\"overview-frame.html\" target=\"profileListFrame\">" + "<span><a href=\"overview-frame.html\" target=\"packageListFrame\">" + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" " - + "target=\"profileListFrame\">All Profiles</a></span>" + + "target=\"packageListFrame\">All Profiles</a></span>" }, {PROFILE_BUG_ID + FS + "compact2-frame.html", "<li><a href=\"pkg4/compact2-package-frame.html\" " @@ -96,11 +96,15 @@ //Test for "overview-frame.html" showing the "All Profiles" link. {PROFILE_BUG_ID + FS + "overview-frame.html", "<span><a href=\"profile-overview-frame.html\" " - + "target=\"profileListFrame\">All Profiles</a></span>" + + "target=\"packageListFrame\">All Profiles</a></span>" }, //Test for "className.html" showing the profile information for the type. {PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", "<div class=\"subTitle\">compact1, compact2, compact3</div>" + }, + {PROFILE_BUG_ID + FS + "index.html", + "<frame src=\"overview-frame.html\" name=\"packageListFrame\" " + + "title=\"All Packages\">" } }; private static final String[][] PROFILES_NEGATED_TEST = { @@ -131,12 +135,12 @@ private static final String[][] PACKAGES_NEGATED_TEST = { {PACKAGE_BUG_ID + FS + "profile-overview-frame.html", "<span><a href=\"overview-frame.html\" " - + "target=\"profileListFrame\">All Packages</a></span>" + + "target=\"packageListFrame\">All Packages</a></span>" }, {PACKAGE_BUG_ID + FS + "compact2-frame.html", - "<span><a href=\"overview-frame.html\" target=\"profileListFrame\">" + "<span><a href=\"overview-frame.html\" target=\"packageListFrame\">" + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" " - + "target=\"profileListFrame\">All Profiles</a></span>" + + "target=\"packageListFrame\">All Profiles</a></span>" }, {PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", "<a href=\"../compact2-summary.html\" target=\"classFrame\">" @@ -151,7 +155,7 @@ }, {PACKAGE_BUG_ID + FS + "overview-frame.html", "<span><a href=\"profile-overview-frame.html\" " - + "target=\"profileListFrame\">All Profiles</a></span>" + + "target=\"packageListFrame\">All Profiles</a></span>" }, {PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", "<div class=\"subTitle\">compact1, compact2, compact3</div>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyPreTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,44 @@ +/* + * 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 8010317 + * @summary DocLint incorrectly reports some <pre> tags as empty + * @build DocLintTester + * @run main DocLintTester -Xmsgs:html EmptyPreTest.java + */ + +public class EmptyPreTest { + /** <pre> {@code xyzzy} </pre> */ + public void m1() { } + + /** <pre> {@docRoot} </pre> */ + public void m2() { } + + /** <pre> {@link java.lang.String} </pre> */ + public void m3() { } + + /** <pre> {@value} </pre> */ + public static final int v1 = 1; +}
--- a/test/tools/javac/4846262/CheckEBCDICLocaleTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/4846262/CheckEBCDICLocaleTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -34,9 +34,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; -import com.sun.tools.javac.util.ArrayUtils; -//original test: test/tools/javac/4846262/Test.sh public class CheckEBCDICLocaleTest { private static final String TestSrc = @@ -46,11 +44,11 @@ " }\n" + "}"; - private static final String TestOut = - "output/Test.java:3: error: not a statement\n" + + private static final String TestOutTemplate = + "output%1$sTest.java:3: error: not a statement\n" + " abcdefg\n" + " ^\n" + - "output/Test.java:3: error: ';' expected\n" + + "output%1$sTest.java:3: error: ';' expected\n" + " abcdefg\n" + " ^\n" + "2 errors\n"; @@ -62,38 +60,37 @@ public void test() throws Exception { String native2asciiBinary = Paths.get( System.getProperty("test.jdk"),"bin", "native2ascii").toString(); - String testVMOpts = System.getProperty("test.tool.vm.opts"); - String[] mainArgs = ToolBox.getJavacBin(); ToolBox.createJavaFileFromSource(TestSrc); Files.createDirectory(Paths.get("output")); -//"${TESTJAVA}${FS}bin${FS}native2ascii" ${TESTTOOLVMOPTS} -reverse -encoding IBM1047 ${TESTSRC}${FS}Test.java Test.java ToolBox.AnyToolArgs nativeCmdParams = new ToolBox.AnyToolArgs() - .setAllArgs(native2asciiBinary, testVMOpts, - "-reverse", "-encoding", "IBM1047", - "Test.java", "output/Test.java"); + .appendArgs(native2asciiBinary) + .appendArgs(ToolBox.testToolVMOpts) + .appendArgs("-reverse", "-encoding", "IBM1047", "Test.java", + "output/Test.java"); ToolBox.executeCommand(nativeCmdParams); -//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -J-Duser.language=en -J-Duser.region=US -J-Dfile.encoding=IBM1047 Test.java 2>Test.tmp ToolBox.AnyToolArgs javacParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) - .setAllArgs(ArrayUtils.concatOpen(mainArgs, "-J-Duser.language=en", + .appendArgs(ToolBox.javacBinary) + .appendArgs(ToolBox.testToolVMOpts) + .appendArgs("-J-Duser.language=en", "-J-Duser.region=US", "-J-Dfile.encoding=IBM1047", - "output/Test.java")) + "output/Test.java") .setErrOutput(new File("Test.tmp")); ToolBox.executeCommand(javacParams); -//"${TESTJAVA}${FS}bin${FS}native2ascii" ${TESTTOOLVMOPTS} -encoding IBM1047 Test.tmp Test.out - nativeCmdParams.setAllArgs(native2asciiBinary, "-encoding", "IBM1047", - "Test.tmp", "Test.out"); + nativeCmdParams = new ToolBox.AnyToolArgs() + .appendArgs(native2asciiBinary) + .appendArgs(ToolBox.testToolVMOpts) + .appendArgs("-encoding", "IBM1047", "Test.tmp", "Test.out"); ToolBox.executeCommand(nativeCmdParams); -//diff ${DIFFOPTS} -c "${TESTSRC}${FS}Test.out" Test.out + String goldenFile = String.format(TestOutTemplate, File.separator); ToolBox.compareLines(Paths.get("Test.out"), - Arrays.asList(TestOut.split("\n")), null); - + Arrays.asList(goldenFile.split("\n")), null, true); } }
--- a/test/tools/javac/ClassFileModifiers/MemberModifiers.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/ClassFileModifiers/MemberModifiers.java Mon Mar 25 18:08:47 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, 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 @@ * @bug 4249112 4785453 * @summary Verify that implicit member modifiers are set correctly. * - * @compile/ref=MemberModifiers.out -source 1.4 -target 1.4.2 -Xlint:-options -XDdumpmodifiers=cfm MemberModifiers.java + * @compile/ref=MemberModifiers.out -source 1.4 -target 1.5 -Xlint:-options -XDdumpmodifiers=cfm MemberModifiers.java */ // Currently, we check only that members of final classes are not final.
--- a/test/tools/javac/ClassPathTest/ClassPathTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/ClassPathTest/ClassPathTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -31,9 +31,11 @@ */ import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.TreeMap; -import com.sun.tools.javac.util.ArrayUtils; //original test: test/tools/javac/ClassPathTest/ClassPathTest.sh public class ClassPathTest { @@ -92,24 +94,31 @@ } void checkCompileCommands() throws Exception { - String[] mainArgs = ToolBox.getJavacBin(); - // Without the -cp . parameter the command will fail seems like when called // from the command line, the current dir is added to the classpath // automatically but this is not happening when called using ProcessBuilder // testJavac success ClassPathTest3.java - String[] commonArgs = ArrayUtils.concatOpen(mainArgs, "-cp", "."); + List<String> mainArgs = new ArrayList<>(); + mainArgs.add(ToolBox.javacBinary.toString()); + if (ToolBox.testToolVMOpts != null) { + mainArgs.addAll(ToolBox.testToolVMOpts); + } - ToolBox.AnyToolArgs successParams = - new ToolBox.AnyToolArgs() - .setAllArgs(ArrayUtils.concatOpen(commonArgs, "ClassPathTest3.java")); + List<String> commonArgs = new ArrayList<>(); + commonArgs.addAll(mainArgs); + commonArgs.addAll(Arrays.asList("-cp", ".")); + + ToolBox.AnyToolArgs successParams = new ToolBox.AnyToolArgs() + .appendArgs(commonArgs) + .appendArgs("ClassPathTest3.java"); ToolBox.executeCommand(successParams); // testJavac failure ClassPathTest1.java ToolBox.AnyToolArgs failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) - .setAllArgs(ArrayUtils.concatOpen(commonArgs, "ClassPathTest1.java")); + .appendArgs(commonArgs) + .appendArgs("ClassPathTest1.java"); ToolBox.executeCommand(failParams); // This is done inside the executeCommand method @@ -119,29 +128,50 @@ extVars.put("CLASSPATH", "bar"); // testJavac success ClassPathTest2.java - successParams.setAllArgs(ArrayUtils.concatOpen(mainArgs, "ClassPathTest2.java")).set(extVars); + successParams = new ToolBox.AnyToolArgs() + .appendArgs(mainArgs) + .appendArgs("ClassPathTest2.java") + .set(extVars); ToolBox.executeCommand(successParams); // testJavac failure ClassPathTest1.java - failParams.setAllArgs(ArrayUtils.concatOpen(mainArgs, "ClassPathTest1.java")).set(extVars); + failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) + .appendArgs(mainArgs) + .appendArgs("ClassPathTest1.java") + .set(extVars); ToolBox.executeCommand(failParams); // testJavac failure ClassPathTest3.java - failParams.setAllArgs(ArrayUtils.concatOpen(mainArgs, "ClassPathTest3.java")); + failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) + .appendArgs(mainArgs) + .appendArgs("ClassPathTest3.java") + .set(extVars); ToolBox.executeCommand(failParams); // testJavac success -classpath foo ClassPathTest1.java - commonArgs = ArrayUtils.concatOpen(mainArgs, "-cp", "foo"); - successParams.setAllArgs(ArrayUtils.concatOpen(commonArgs, "ClassPathTest1.java")); + commonArgs.clear(); + commonArgs.addAll(mainArgs); + commonArgs.addAll(Arrays.asList("-cp", "foo")); + + successParams = new ToolBox.AnyToolArgs() + .appendArgs(commonArgs) + .appendArgs("ClassPathTest1.java") + .set(extVars); ToolBox.executeCommand(successParams); // testJavac failure -classpath foo ClassPathTest2.java - failParams.setAllArgs(ArrayUtils.concatOpen(commonArgs, "ClassPathTest2.java")); + failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) + .appendArgs(commonArgs) + .appendArgs("ClassPathTest2.java") + .set(extVars); ToolBox.executeCommand(failParams); // testJavac failure -classpath foo ClassPathTest3.java - failParams.setAllArgs(ArrayUtils.concatOpen(commonArgs, "ClassPathTest3.java")); + failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) + .appendArgs(commonArgs) + .appendArgs("ClassPathTest3.java") + .set(extVars); ToolBox.executeCommand(failParams); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/Diagnostics/8010387/T8010387.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,17 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8010387 + * @summary rich diagnostic sometimes contain wrong type variable numbering + * @compile/fail/ref=T8010387.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T8010387.java + */ +abstract class T8010387<X> { + + interface F<X> { } + + <P> void test() { + m(new F<P>() { }); + } + + + abstract <T> T8010387<?> m(F<? extends X> fx); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/Diagnostics/8010387/T8010387.out Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,3 @@ +T8010387.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, T8010387.F<? extends X>, compiler.misc.anonymous.class: T8010387.F<P>, kindname.class, T8010387<X>, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: compiler.misc.anonymous.class: T8010387.F<P>, T8010387.F<? extends X>)) +- compiler.misc.where.description.typevar.1: X,P,T,{(compiler.misc.where.typevar: X, java.lang.Object, kindname.class, T8010387),(compiler.misc.where.typevar: P, java.lang.Object, kindname.method, <P>test()),(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, <T>m(T8010387.F<? extends X>))} +1 error
--- a/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -91,7 +91,9 @@ //"${TESTJAVA}${FS}bin${FS}java" ${TESTVMOPTS} -classpath "${CLASSPATH}${PS}${TESTCLASSES}" p2.ProtectedInnerClass2 ToolBox.AnyToolArgs javaParams = new ToolBox.AnyToolArgs() - .setAllArgs(ToolBox.javaBinary, "-classpath", System.getProperty("user.dir"), + .appendArgs(ToolBox.javaBinary) + .appendArgs(ToolBox.testVMOpts) + .appendArgs("-classpath", System.getProperty("user.dir"), "p2.ProtectedInnerClass2"); ToolBox.executeCommand(javaParams); } @@ -101,14 +103,15 @@ //@run compile p1/ProtectedInnerClass1.java ToolBox.JavaToolArgs javacParams = new ToolBox.JavaToolArgs() - .setOptions("-d", ".") + .appendArgs("-d", ".") .setSources(protectedInnerClass1Src); ToolBox.javac(javacParams); //@run compile/fail p2/ProtectedInnerClass3.java - javacParams.setSources(protectedInnerClass3Src) - .set(ToolBox.Expect.FAIL); + javacParams = new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL) + .appendArgs("-d", ".") + .setSources(protectedInnerClass3Src); ToolBox.javac(javacParams); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T5053846/MethodRefDupInConstantPoolTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,91 @@ +/* + * 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 5053846 + * @summary javac: MethodRef entries are duplicated in the constant pool + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Paths; +import java.util.*; + +public class MethodRefDupInConstantPoolTest { + + private static final String methodToLookFor = + "java/util/Vector.iterator:()Ljava/util/Iterator;"; + + public static void main(String[] args) { + new MethodRefDupInConstantPoolTest().run(); + } + + void run() { + check("-v", Paths.get(System.getProperty("test.classes"), + "TestHelper1.class").toString()); + check("-v", Paths.get(System.getProperty("test.classes"), + "TestHelper2.class").toString()); + } + + void check(String... params) { + StringWriter s; + String out; + try (PrintWriter pw = new PrintWriter(s = new StringWriter())) { + com.sun.tools.javap.Main.run(params, pw); + out = s.toString(); + } + String constantPool = getConstantPool(out); + if (constantPool.indexOf(methodToLookFor) != + constantPool.lastIndexOf(methodToLookFor)) { + throw new AssertionError("There is more than one entry for the method seek " + + methodToLookFor); + } + } + + String getConstantPool(String out) { + int start = out.indexOf("Constant pool:"); + int end = out.indexOf("{"); + return out.substring(start, end); + } +} + +class TestHelper1 { + void m() { + Vector v = new Vector(); + Iterator iter = v.iterator(); + while (iter.hasNext()) { + Object o = iter.next(); + Object o2 = o; + } + for (Object o: v) { + Object o2 = o; + } + } +} + +class TestHelper2<X extends Number & Iterable<String>> { + void test(X x) { + for (String s : x) { } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/DefaultTarget.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.*; + +/** + * @test + * @bug 8006547 + * @compile DefaultTarget.java + */ + +@Target({ + ElementType.CONSTRUCTOR, + ElementType.PARAMETER, + ElementType.TYPE, + ElementType.METHOD, + ElementType.LOCAL_VARIABLE, + ElementType.PACKAGE, + ElementType.ANNOTATION_TYPE, + ElementType.FIELD, +}) +@interface Container { + DefaultTarget[] value(); +} + +@Repeatable(Container.class) +public @interface DefaultTarget {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeParameter.java Mon Mar 25 18:08:47 2013 -0700 @@ -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. + */ + +import java.lang.annotation.*; + +/** + * @test + * @bug 8006547 + * @compile/fail/ref=DefaultTargetTypeParameter.out -XDrawDiagnostics DefaultTargetTypeParameter.java + */ + +@Target({ + ElementType.TYPE_PARAMETER, +}) +@interface Container { + DefaultTargetTypeParameter[] value(); +} + +@Repeatable(Container.class) +public @interface DefaultTargetTypeParameter {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeParameter.out Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,2 @@ +DefaultTargetTypeParameter.java:39:1: compiler.err.invalid.repeatable.annotation.incompatible.target: Container, DefaultTargetTypeParameter +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeUse.java Mon Mar 25 18:08:47 2013 -0700 @@ -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. + */ + +import java.lang.annotation.*; + +/** + * @test + * @bug 8006547 + * @compile/fail/ref=DefaultTargetTypeUse.out -XDrawDiagnostics DefaultTargetTypeUse.java + */ + +@Target({ + ElementType.TYPE_USE, +}) +@interface Container { + DefaultTargetTypeUse[] value(); +} + +@Repeatable(Container.class) +public @interface DefaultTargetTypeUse {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeUse.out Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,2 @@ +DefaultTargetTypeUse.java:39:1: compiler.err.invalid.repeatable.annotation.incompatible.target: Container, DefaultTargetTypeUse +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/NoTargetOnContainer.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.*; + +/** + * @test + * @bug 8006547 + * @compile NoTargetOnContainer.java + */ + +@interface FooContainer { + Foo[] value(); +} + +@Target({ + ElementType.CONSTRUCTOR, + ElementType.PARAMETER, + ElementType.TYPE, + ElementType.METHOD, + ElementType.LOCAL_VARIABLE, + ElementType.PACKAGE, + ElementType.ANNOTATION_TYPE, + ElementType.FIELD, +}) +@Repeatable(FooContainer.class) +@interface Foo {} + +class NoTargetOnContainer {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/NoTargetOnContainer2.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.*; + +/** + * @test + * @bug 8006547 + * @compile NoTargetOnContainer2.java + */ + +@interface FooContainer { + Foo[] value(); +} + +@Target({ + ElementType.CONSTRUCTOR, + ElementType.PARAMETER, + ElementType.TYPE, + ElementType.METHOD, + ElementType.LOCAL_VARIABLE, + ElementType.PACKAGE, + ElementType.ANNOTATION_TYPE, + ElementType.FIELD, + ElementType.TYPE_USE, + ElementType.TYPE_PARAMETER}) +@Repeatable(FooContainer.class) +@interface Foo {} + +class NoTargetOnContainer2 {}
--- a/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Mon Mar 25 18:08:47 2013 -0700 @@ -146,6 +146,7 @@ public static final String template = "/*PACKAGE*/\n" + "//pkg test;\n\n" + + "/*ANNODATA*/\n" // import statements, declaration of Foo/FooContainer + "/*TYPE*/ //class\n" + "class #ClassName {\n" + " /*FIELD*/ //instance var\n"
--- a/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Mon Mar 25 18:08:47 2013 -0700 @@ -21,245 +21,404 @@ * questions. */ -/** +/* * @test - * @bug 7195131 - * @author sogoel - * @summary Combo test for all possible combinations for Target values - * @ignore 8008339 Test TargetAnnoCombo.java is broken + * @bug 7151010 8006547 8007766 + * @summary Default test cases for running combinations for Target values * @build Helper - * @compile TargetAnnoCombo.java TestCaseGenerator.java * @run main TargetAnnoCombo */ +import java.util.Set; +import java.util.List; import java.io.IOException; +import java.lang.annotation.ElementType; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.EnumSet; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.JavaFileObject; -/* - * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator. - * For each of the test case number, @Target sets for base and container annotations - * are determined, source files are generated, compiled, and the result is verified - * based on if the @Target set for base and container is a positive or negative combination. - * - * @Target sets for base and container annotations are determined using a bit mapping of - * 10 ElementType enum constants defined in JDK8. - * - * Bit Target value - * 0 "ElementType.ANNOTATION_TYPE" - * 1 "ElementType.CONSTRUCTOR" - * 2 "ElementType.FIELD" - * 3 "ElementType.LOCAL_VARIABLE" - * 4 "ElementType.METHOD" - * 5 "ElementType.TYPE" - * 6 "ElementType.PARAMETER" - * 7 "ElementType.PACKAGE" - * 8 "ElementType.TYPE_USE" - * 9 "ElementType.TYPE_PARAMETER" - * - * Group 1: - * 20 bits mapping, representing a test case number, is used for all target set - * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}). - * From this 20 bits, 10 bits are for base followed by 10 bits for container - * where each bit maps to an ElementType enum constant defined in JDK8. - * - * Examples: - * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"] - * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111; - * base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"], - * container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"] - * - * In the following groups, no @Target set is represented by null. - * Group 2: - * @Target is not defined on base. - * Target sets for container are determined using the 10-bit binary number - * resulting in 1024 test cases, mapping them to test case numbers from - * 1048576 to (1048576 + 1023) => 1048576 to 1049599. - * - * Example: - * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 => - * base = null, - * container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"] - * - * Group 3: - * @Target is not defined on container - * Target sets for base are determined using the 10-bit binary number - * resulting in 1024 test cases, mapping them to test case numbers from - * 1049600 to (1049600 + 1023) => 1049600 to 1050623. - * - * Example: - * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 => - * base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"], - * container = null - * - * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed - * - * Group 4: - * @Target not defined for both base and container annotations. - * - * This is the last test and corresponds to test case number 1050624. base=null, container=null - * - * Examples to run this test: - * 1. Run a specific test case number: - * ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java - * 2. Run specific number of tests: - * ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java - * 3. Run specific number of tests with a seed: - * ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java - * 4. Run tests in default mode (number of tests = 1000): - * ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java - * 5. Run all tests (FULL mode): - * ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java - * - */ +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.ElementType.TYPE_PARAMETER; public class TargetAnnoCombo { - int errors = 0; + static final String TESTPKG = "testpkg"; - /* - * Set it to true to get more debug information including base and - * container target sets for a given test case number - */ + + // Set it to true to get more debug information including base and container + // target sets for a given test case. static final boolean DEBUG = false; - // JDK 5/6/7/8 Targets - static final String[] targetVals = {"ElementType.ANNOTATION_TYPE", - "ElementType.CONSTRUCTOR", "ElementType.FIELD", - "ElementType.LOCAL_VARIABLE", "ElementType.METHOD", - "ElementType.TYPE", "ElementType.PARAMETER", - "ElementType.PACKAGE", "ElementType.TYPE_USE", - "ElementType.TYPE_PARAMETER"}; + // Define constant target sets to be used for the combination of the target values. + final static Set<ElementType> noSet = null; + final static Set<ElementType> empty = EnumSet.noneOf(ElementType.class); + + // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, + // PACKAGE, TYPE_PARAMETER, TYPE_USE] + final static Set<ElementType> allTargets = EnumSet.allOf(ElementType.class); + + // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, + // PACKAGE] + final static Set<ElementType> jdk7 = EnumSet.range(TYPE, PACKAGE); + + // [TYPE_USE, TYPE_PARAMETER] + final static Set<ElementType> jdk8 = EnumSet.range(TYPE_PARAMETER, TYPE_USE); + + // List of test cases to run. This list is created in generate(). + // To run a specific test cases add case number in @run main line. + List<TestCase> testCases = new ArrayList<TestCase>(); + + int errors = 0; + + // Identify test cases that fail. + enum IgnoreKind { + RUN, + IGNORE + }; + + private class TestCase { + + private Set<ElementType> baseAnnotations; + private Set<ElementType> containerAnnotations; + private IgnoreKind ignore; + + public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations) { + this(baseAnnotations, containerAnnotations, IgnoreKind.RUN); + } + + public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations, + IgnoreKind ignoreKind) { + this.baseAnnotations = baseAnnotations; + this.containerAnnotations = containerAnnotations; + this.ignore = ignoreKind; + } + + public Set getBaseAnnotations() { + return baseAnnotations; + } + + public Set getContainerAnnotations() { + return containerAnnotations; + } + + public boolean isIgnored() { + return ignore == IgnoreKind.IGNORE; + } - // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set - static final int DEFAULT_TARGET_CNT = 8; + // Determine if a testCase should compile or not. + private boolean isValidSubSet() { + /* + * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget + * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere + * - Empty sets for both is valid + * - Empty baseTarget set is invalid with non-empty conTarget set + * - Non-empty baseTarget set is valid with empty conTarget set + * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets + * - No @Target for both is valid + * - No @Target for baseTarget set with @Target conTarget set is valid + * - @Target for baseTarget set with no @Target for conTarget is invalid + */ + + + /* If baseAnno has no @Target, Foo can be either applied to @Target specified + * for container annotation else will be applicable for all default targets + * if no @Target is present for container annotation. + * In both cases, the set will be a valid set with no @Target for base annotation + */ + if (baseAnnotations == null) { + if (containerAnnotations == null) { + return true; + } + return !(containerAnnotations.contains(TYPE_USE) || + containerAnnotations.contains(TYPE_PARAMETER)); + } + + Set<ElementType> tempBaseSet = EnumSet.noneOf(ElementType.class); + tempBaseSet.addAll(baseAnnotations); + // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default. + if (baseAnnotations.contains(TYPE)) { + tempBaseSet.add(ANNOTATION_TYPE); + } + + // If containerAnno has no @Target, only valid case if baseAnnoTarget has + // all targets defined else invalid set. + if (containerAnnotations == null) { + return tempBaseSet.containsAll(jdk7); + } + + // At this point, neither conAnnoTarget or baseAnnoTarget are null. + if (containerAnnotations.isEmpty()) { + return true; + } + + // At this point, conAnnoTarget is non-empty. + if (baseAnnotations.isEmpty()) { + return false; + } + + // At this point, neither conAnnoTarget or baseAnnoTarget are empty. + return tempBaseSet.containsAll(containerAnnotations); + } + } public static void main(String args[]) throws Exception { - - /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos]) - * + (combinations where base or container has no Target [1024 combos]) - * + (no -1 even though 1st test is number 0 as last test is where both - * base and container have no target) - */ - - int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length); - TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum); TargetAnnoCombo tac = new TargetAnnoCombo(); - - int testCtr = 0; - int testCase = -1; - while ( (testCase=tcg.getNextTestCase()) != -1 ) { - tac.executeTestCase(testCase, maxTestNum); - testCtr++; + // Generates all test cases to be run. + tac.generate(); + List<Integer> cases = new ArrayList<Integer>(); + for (int i = 0; i < args.length; i++) { + cases.add(Integer.parseInt(args[i])); } - - System.out.println("Total tests run: " + testCtr); - if (tac.errors > 0) - throw new Exception(tac.errors + " errors found"); + if (cases.isEmpty()) { + tac.run(); + } else { + for (int index : cases) { + tac.executeTestCase(tac.testCases.get(index), index); + } + } } - /* - * For given testCase, determine the base and container annotation Target sets, - * get if testCase should compile, get test source file(s), get compilation result and verify. - * - */ - private void executeTestCase(int testCase, int maxTestNum) { - - // Determine base and container annotation Target sets for the testCase - Set<String> baseAnnoTarget = null; - Set<String> conAnnoTarget = null; - - //Number of base and container combinations [0 - 1048575 combos] - int baseContCombos = (int)Math.pow(2, 2*targetVals.length); - //Number of either base or container combinations when one of them has no @Target [1024 combos] - int targetValsCombos = (int)Math.pow(2, targetVals.length); - - if (testCase >= baseContCombos) { - //Base annotation do not have @Target - if (testCase < baseContCombos + targetValsCombos) { - baseAnnoTarget = null; - conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos)); - } else if (testCase < baseContCombos + 2*targetValsCombos) { - //Container annotation do not have @Target - baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos)); - conAnnoTarget = null; - } else { - //Both Base and Container annotation do not have @Target - baseAnnoTarget = null; - conAnnoTarget = null; + private void generate() { + // Adding test cases to run. + testCases.addAll(Arrays.asList( + // No base target against no container target. + new TestCase(noSet, noSet), + // No base target against empty container target. + new TestCase(noSet, empty), + // No base target against TYPE_USE only container target. + new TestCase(noSet, less(jdk8, TYPE_PARAMETER)), + // No base target against TYPE_PARAMETER only container target. + new TestCase(noSet, less(jdk8, TYPE_USE)), + // No base target against TYPE_USE + TYPE_PARAMETER only container target. + new TestCase(noSet, jdk8), + // No base target against TYPE_USE + some selection of jdk7 targets. + new TestCase(noSet, + plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_USE)), + // No base target against TYPE_PARAMETER + some selection of jdk7 targets. + new TestCase(noSet, + plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_PARAMETER)), + // No base target against each jdk7 target alone as container target. + new TestCase(noSet, plus(empty, TYPE)), + new TestCase(noSet, plus(empty, PARAMETER)), + new TestCase(noSet, plus(empty, PACKAGE)), + new TestCase(noSet, plus(empty, METHOD)), + new TestCase(noSet, plus(empty, LOCAL_VARIABLE)), + new TestCase(noSet, plus(empty, FIELD)), + new TestCase(noSet, plus(empty, CONSTRUCTOR)), + new TestCase(noSet, plus(empty, ANNOTATION_TYPE)), + // Empty base target against no container target. + new TestCase(empty, noSet), + // Empty base target against empty container target. + new TestCase(empty, empty), + // Empty base target against any lone container target. + new TestCase(empty, plus(empty, TYPE)), + new TestCase(empty, plus(empty, PARAMETER)), + new TestCase(empty, plus(empty, PACKAGE)), + new TestCase(empty, plus(empty, METHOD)), + new TestCase(empty, plus(empty, LOCAL_VARIABLE)), + new TestCase(empty, plus(empty, FIELD)), + new TestCase(empty, plus(empty, CONSTRUCTOR)), + new TestCase(empty, plus(empty, ANNOTATION_TYPE)), + new TestCase(empty, less(jdk8, TYPE_USE)), + new TestCase(empty, less(jdk8, TYPE_PARAMETER)), + // No container target against all all-but one jdk7 targets. + new TestCase(less(jdk7, TYPE), noSet), + new TestCase(less(jdk7, PARAMETER), noSet), + new TestCase(less(jdk7, PACKAGE), noSet), + new TestCase(less(jdk7, METHOD), noSet), + new TestCase(less(jdk7, LOCAL_VARIABLE), noSet), + new TestCase(less(jdk7, FIELD), noSet), + new TestCase(less(jdk7, CONSTRUCTOR), noSet), + new TestCase(less(jdk7, ANNOTATION_TYPE), noSet), + // No container against all but TYPE and ANNOTATION_TYPE + new TestCase(less(jdk7, TYPE, ANNOTATION_TYPE), noSet), + // No container against jdk7 targets. + new TestCase(jdk7, noSet), + // No container against jdk7 targets plus one or both of TYPE_USE, TYPE_PARAMETER + new TestCase(plus(jdk7, TYPE_USE), noSet), + new TestCase(plus(jdk7, TYPE_PARAMETER), noSet), + new TestCase(allTargets, noSet), + // Empty container target against any lone target. + new TestCase(plus(empty, TYPE), empty), + new TestCase(plus(empty, PARAMETER), empty), + new TestCase(plus(empty, PACKAGE), empty), + new TestCase(plus(empty, METHOD), empty), + new TestCase(plus(empty, LOCAL_VARIABLE), empty), + new TestCase(plus(empty, FIELD), empty), + new TestCase(plus(empty, CONSTRUCTOR), empty), + new TestCase(plus(empty, ANNOTATION_TYPE), empty), + new TestCase(plus(empty, TYPE_USE), empty), + new TestCase(plus(empty, TYPE_PARAMETER), empty), + // All base targets against all container targets. + new TestCase(allTargets, allTargets), + // All base targets against all but one container targets. + new TestCase(allTargets, less(allTargets, TYPE)), + new TestCase(allTargets, less(allTargets, PARAMETER)), + new TestCase(allTargets, less(allTargets, PACKAGE)), + new TestCase(allTargets, less(allTargets, METHOD)), + new TestCase(allTargets, less(allTargets, LOCAL_VARIABLE)), + new TestCase(allTargets, less(allTargets, FIELD)), + new TestCase(allTargets, less(allTargets, CONSTRUCTOR)), + new TestCase(allTargets, less(allTargets, ANNOTATION_TYPE)), + new TestCase(allTargets, less(allTargets, TYPE_USE)), + new TestCase(allTargets, less(allTargets, TYPE_PARAMETER)), + // All container targets against all but one base targets. + new TestCase(less(allTargets, TYPE), allTargets), + new TestCase(less(allTargets, PARAMETER), allTargets), + new TestCase(less(allTargets, PACKAGE), allTargets), + new TestCase(less(allTargets, METHOD), allTargets), + new TestCase(less(allTargets, LOCAL_VARIABLE), allTargets), + new TestCase(less(allTargets, FIELD), allTargets), + new TestCase(less(allTargets, CONSTRUCTOR), allTargets), + new TestCase(less(allTargets, ANNOTATION_TYPE), allTargets), + new TestCase(less(allTargets, TYPE_USE), allTargets), + new TestCase(less(allTargets, TYPE_PARAMETER), allTargets))); + // Generates 100 test cases for any lone base target contained in Set + // allTargets against any lone container target. + for (ElementType b : allTargets) { + for (ElementType c : allTargets) { + testCases.add(new TestCase(plus(empty, b), plus(empty, c))); } - } else { - //TestCase number is represented as 10-bits for base followed by container bits - String bin = Integer.toBinaryString(testCase); - String base="", cont=bin; - if (bin.length() > targetVals.length){ - base = bin.substring(0, bin.length() - targetVals.length); - cont = bin.substring(bin.length() - targetVals.length,bin.length()); - } - baseAnnoTarget = getSetFromBitVec(base); - conAnnoTarget = getSetFromBitVec(cont); } - - debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase)); - debugPrint(" => baseAnnoTarget = " + baseAnnoTarget); - debugPrint(" => containerAnnoTarget = " + conAnnoTarget); + } - // Determine if a testCase should compile or not - String className = "TC" + testCase; - boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget); - - // Get test source file(s) - Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget, - conAnnoTarget, shouldCompile); + void run() throws Exception { + int testCtr = 0; + for (TestCase tc : testCases) { + if (!tc.isIgnored()) { + executeTestCase(tc, testCases.indexOf(tc)); + testCtr++; + } + } + System.out.println("Total tests run: " + testCtr); + if (errors > 0) { + throw new Exception(errors + " errors found"); + } + } - // Get result of compiling test src file(s) - boolean result = getCompileResult(className, shouldCompile, files); + private void executeTestCase(TestCase testCase, int index) { + debugPrint("Test case number = " + index); + debugPrint(" => baseAnnoTarget = " + testCase.getBaseAnnotations()); + debugPrint(" => containerAnnoTarget = " + testCase.getContainerAnnotations()); - // List test src code if test fails - if(!result) { - System.out.println("FAIL: Test " + testCase); + String className = "TC" + index; + boolean shouldCompile = testCase.isValidSubSet(); + Iterable<? extends JavaFileObject> files = getFileList(className, testCase, shouldCompile); + // Get result of compiling test src file(s). + boolean result = getCompileResult(className, shouldCompile, files); + // List test src code if test fails. + if (!result) { + System.out.println("FAIL: Test " + index); try { - for (JavaFileObject f: files) { + for (JavaFileObject f : files) { System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true)); } } catch (IOException ioe) { System.out.println("Exception: " + ioe); } } else { - debugPrint("PASS: Test " + testCase); + debugPrint("PASS: Test " + index); } + } - // Get a Set<String> based on bits that are set to 1 - public Set<String> getSetFromBitVec(String bitVec) { - Set<String> ret = new HashSet<>(); - char[] bit = bitVec.toCharArray(); - for (int i=bit.length-1, j=0; i>=0; i--, j++){ - if (bit[i] == '1') { - ret.add(targetVals[j]); + // Create src code and corresponding JavaFileObjects. + private Iterable<? extends JavaFileObject> getFileList(String className, + TestCase testCase, boolean shouldCompile) { + Set<ElementType> baseAnnoTarget = testCase.getBaseAnnotations(); + Set<ElementType> conAnnoTarget = testCase.getContainerAnnotations(); + String srcContent = ""; + String pkgInfoContent = ""; + String template = Helper.template; + String baseTarget = "", conTarget = ""; + + String target = Helper.ContentVars.TARGET.getVal(); + if (baseAnnoTarget != null) { + String tmp = target.replace("#VAL", convertToString(baseAnnoTarget).toString()); + baseTarget = tmp.replace("[", "{").replace("]", "}"); + } + if (conAnnoTarget != null) { + String tmp = target.replace("#VAL", convertToString(conAnnoTarget).toString()); + conTarget = tmp.replace("[", "{").replace("]", "}"); + } + + String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() + + conTarget + + Helper.ContentVars.CONTAINER.getVal() + + baseTarget + + Helper.ContentVars.REPEATABLE.getVal() + + Helper.ContentVars.BASE.getVal(); + + JavaFileObject pkgInfoFile = null; + + // If shouldCompile = true and no @Target is specified for container annotation, + // then all 8 ElementType enum constants are applicable as targets for + // container annotation. + if (shouldCompile && conAnnoTarget == null) { + Set<ElementType> copySet = EnumSet.noneOf(ElementType.class); + copySet.addAll(jdk7); + conAnnoTarget = copySet; + } + + if (shouldCompile) { + boolean isPkgCasePresent = conAnnoTarget.contains(PACKAGE); + String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + + " " + Helper.ContentVars.BASEANNO.getVal(); + for (ElementType s : conAnnoTarget) { + String replaceStr = "/*" + s.name() + "*/"; + if (s.name().equalsIgnoreCase("PACKAGE")) { + //Create packageInfo file. + String pkgInfoName = TESTPKG + "." + "package-info"; + pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData; + pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent); + } else { + template = template.replace(replaceStr, repeatableAnno); + if (!isPkgCasePresent) { + srcContent = template.replace( + "/*ANNODATA*/", annoData).replace("#ClassName", className); + } else { + replaceStr = "/*PACKAGE*/"; + String tmp = template.replace(replaceStr, "package " + TESTPKG + ";"); + srcContent = tmp.replace("#ClassName", className); + } + } } + } else { + // For invalid cases, compilation should fail at declaration site. + template = "class #ClassName {}"; + srcContent = annoData + template.replace("#ClassName", className); } - return ret; + JavaFileObject srcFile = Helper.getFile(className, srcContent); + Iterable<? extends JavaFileObject> files = null; + if (pkgInfoFile != null) { + files = Arrays.asList(pkgInfoFile, srcFile); + } else { + files = Arrays.asList(srcFile); + } + return files; } - // Compile the test source file(s) and return test result + // Compile the test source file(s) and return test result. private boolean getCompileResult(String className, boolean shouldCompile, Iterable<? extends JavaFileObject> files) { DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); Helper.compileCode(diagnostics, files); - - // Test case pass or fail + // Test case pass or fail. boolean ok = false; - String errMesg = ""; int numDiags = diagnostics.getDiagnostics().size(); - if (numDiags == 0) { if (shouldCompile) { debugPrint("Test passed, compiled as expected."); @@ -270,201 +429,80 @@ } } else { if (shouldCompile) { - // did not compile + // did not compile. errMesg = "Test failed, did not compile."; ok = false; } else { - // Error in compilation as expected - String expectedErrKey = "compiler.err.invalid.repeatable." + - "annotation.incompatible.target"; + // Error in compilation as expected. + String expectedErrKey = "compiler.err.invalid.repeatable." + + "annotation.incompatible.target"; for (Diagnostic<?> d : diagnostics.getDiagnostics()) { - if((d.getKind() == Diagnostic.Kind.ERROR) && - d.getCode().contains(expectedErrKey)) { - // Error message as expected + if ((d.getKind() == Diagnostic.Kind.ERROR) + && d.getCode().contains(expectedErrKey)) { + // Error message as expected. debugPrint("Error message as expected."); ok = true; break; } else { - // error message is incorrect + // error message is incorrect. ok = false; } } if (!ok) { - errMesg = "Incorrect error received when compiling " + - className + ", expected: " + expectedErrKey; + errMesg = "Incorrect error received when compiling " + + className + ", expected: " + expectedErrKey; } } } - if(!ok) { + if (!ok) { error(errMesg); - for (Diagnostic<?> d : diagnostics.getDiagnostics()) + for (Diagnostic<?> d : diagnostics.getDiagnostics()) { System.out.println(" Diags: " + d); + } } return ok; } - private void debugPrint(String string) { - if(DEBUG) - System.out.println(string); + private Set<ElementType> less(Set<ElementType> base, ElementType... sub) { + Set<ElementType> res = EnumSet.noneOf(ElementType.class); + res.addAll(base); + for (ElementType t : sub) { + res.remove(t); + } + return res; + } + + private Set<ElementType> plus(Set<ElementType> base, ElementType... add) { + Set<ElementType> res = EnumSet.noneOf(ElementType.class); + res.addAll(base); + for (ElementType t : add) { + res.add(t); + } + return res; } - // Create src code and corresponding JavaFileObjects - private Iterable<? extends JavaFileObject> getFileList(String className, - Set<String> baseAnnoTarget, Set<String> conAnnoTarget, - boolean shouldCompile) { - - String srcContent = ""; - String pkgInfoContent = ""; - String template = Helper.template; - String baseTarget = "", conTarget = ""; - - String target = Helper.ContentVars.TARGET.getVal(); - if(baseAnnoTarget != null) { - baseTarget = target.replace("#VAL", baseAnnoTarget.toString()) - .replace("[", "{").replace("]", "}"); - } - if(conAnnoTarget != null) { - conTarget = target.replace("#VAL", conAnnoTarget.toString()) - .replace("[", "{").replace("]", "}"); + // Iterate target set and add "ElementType." in front of every target type. + private List<String> convertToString(Set<ElementType> annoTarget) { + if (annoTarget == null) { + return null; } - - String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() + - conTarget + - Helper.ContentVars.CONTAINER.getVal() + - baseTarget + - Helper.ContentVars.REPEATABLE.getVal() + - Helper.ContentVars.BASE.getVal(); - - JavaFileObject pkgInfoFile = null; - - /* - * If shouldCompile = true and no @Target is specified for container annotation, - * then all 8 ElementType enum constants are applicable as targets for - * container annotation. - */ - if(shouldCompile && conAnnoTarget == null) { - //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals)); - conAnnoTarget = getDefaultTargetSet(); + List<String> annoTargets = new ArrayList<String>(); + for (ElementType e : annoTarget) { + annoTargets.add("ElementType." + e.name()); } - - if(shouldCompile) { - boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE"); - String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal(); - for(String s: conAnnoTarget) { - s = s.replace("ElementType.",""); - String replaceStr = "/*"+s+"*/"; - if(s.equalsIgnoreCase("PACKAGE")) { - //Create packageInfo file - String pkgInfoName = TESTPKG + "." + "package-info"; - pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData; - pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent); - } else { - template = template.replace(replaceStr, repeatableAnno); - //srcContent = template.replace("#ClassName",className); - if(!isPkgCasePresent) { - srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className); - } else { - replaceStr = "/*PACKAGE*/"; - srcContent = template.replace(replaceStr, "package " + TESTPKG + ";") - .replace("#ClassName", className); - } - } - } - } else { - // For invalid cases, compilation should fail at declaration site - template = "class #ClassName {}"; - srcContent = annoData + template.replace("#ClassName",className); - } - JavaFileObject srcFile = Helper.getFile(className, srcContent); - Iterable<? extends JavaFileObject> files = null; - if(pkgInfoFile != null) - files = Arrays.asList(pkgInfoFile,srcFile); - else - files = Arrays.asList(srcFile); - return files; + return annoTargets; } - private Set<String> getDefaultTargetSet() { - Set<String> defaultSet = new HashSet<>(); - int ctr = 0; - for(String s : targetVals) { - if(ctr++ < DEFAULT_TARGET_CNT) { - defaultSet.add(s); - } + private void debugPrint(String string) { + if (DEBUG) { + System.out.println(string); } - return defaultSet; } - private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) { - /* - * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget - * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere - * - Empty sets for both is valid - * - Empty baseTarget set is invalid with non-empty conTarget set - * - Non-empty baseTarget set is valid with empty conTarget set - * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets - * - No @Target for both is valid - * - No @Target for baseTarget set with @Target conTarget set is valid - * - @Target for baseTarget set with no @Target for conTarget is invalid - */ - - - /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation - * else will be applicable for all default targets if no @Target is present for container annotation. - * In both cases, the set will be a valid set with no @Target for base annotation - */ - if(baseAnnoTarget == null) { - if(conAnnoTarget == null) return true; - return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER")); - } - - Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget); - // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default - if(baseAnnoTarget.contains("ElementType.TYPE")) { - tempBaseSet.add("ElementType.ANNOTATION_TYPE"); - } - - /* - * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined - * else invalid set - */ - if(conAnnoTarget == null) { - return (tempBaseSet.containsAll(getDefaultTargetSet())); - } - - // At this point, neither conAnnoTarget or baseAnnoTarget are null - if(conAnnoTarget.size() == 0) return true; - - // At this point, conAnnoTarget is non-empty - if (baseAnnoTarget.size() == 0) return false; - - // At this point, neither conAnnoTarget or baseAnnoTarget are empty - return tempBaseSet.containsAll(conAnnoTarget); - } - - void error(String msg) { + private void error(String msg) { System.out.println("ERROR: " + msg); errors++; } - - // Lists the start and end range for the given set of target vals - void showGroups() { - //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}) - int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1; - System.out.println("[Group 1]: 0 - " + grpEnd1); +} - //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ). - System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - "); - int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1; - System.out.println(grpEnd2); - - //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ). - System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - "); - int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1; - System.out.println(grpEnd3); - - //Group 4: @Target not defined for both base and container annotations ( 1050624 ). - System.out.println("[Group 4]: " + (grpEnd3 + 1)); - } -}
--- a/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java Mon Mar 25 16:55:14 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* - * 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.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Random; - -/* System properties: - * NumberOfTests, TestMode, and TestCaseNum are mutually exclusive - * TestSeed will be used only with NumberOfTests or TestMode, otherwise it will be ignored - * -DNumberOfTests=[0 to 2^20+2^11+1] - * -DTestMode=[FULL|DEFAULT] - * -DTestSeed=[seedNumber] - * -DTestCaseNum=[0 to 2^20+2^11+1] - */ -public class TestCaseGenerator { - // Total number of tests to be run - int numberOfTests = -1; - //Single test case - int testCaseNum = -1; - //Seed used to generate test cases - int testSeed; - - int maxTestNum; - Random randNum; - - // used in getNextTestCase - int curTestNum; - int testCompletedCount; - HashSet<Integer> uniqueTestSet; - - static final int DEFAULT_TEST_COUNT = 250; - - /* - * Get parameter values from command line to set numberOfTests, testCaseNum, - * and testSeed - */ - public TestCaseGenerator(int maxTestNum) { - this.maxTestNum = maxTestNum; - - // Set values for variables based on input from command line - - // TestMode system property - String testModeVal = System.getProperty("TestMode"); - if(testModeVal != null && !testModeVal.isEmpty()) { - switch (testModeVal.toUpperCase()) { - case "FULL": - numberOfTests = maxTestNum; - break; - case "DEFAULT": - numberOfTests = DEFAULT_TEST_COUNT; - break; - default: - System.out.println("Invalid property value " + testModeVal + - " for numberOfTests. Possible range: 0 to " + - maxTestNum + ". Ignoring property"); - numberOfTests = -1; - } - } - - // NumberOfTests system property - String numTestsStr = System.getProperty("NumberOfTests"); - if(numTestsStr != null && !numTestsStr.isEmpty()) { - int numTests = -1; - try { - numTests = Integer.parseInt(numTestsStr); - if (numTests < 0 || numTests > maxTestNum) { - throw new NumberFormatException(); - } - } catch(NumberFormatException nfe) { - System.out.println("Invalid NumberOfTests property value " + - numTestsStr + ". Possible range: 0 to " + maxTestNum + - "Reset to default: " + DEFAULT_TEST_COUNT); - numTests = DEFAULT_TEST_COUNT; - } - - if (numberOfTests != -1 && numTests != -1) { - System.out.println("TestMode and NumberOfTests cannot be set together. Ignoring TestMode."); - } - numberOfTests = numTests; - } - - // TestSeed system property - String seedVal = System.getProperty("TestSeed"); - if(seedVal != null && !seedVal.isEmpty()) { - try { - testSeed = Integer.parseInt(seedVal); - } catch(NumberFormatException nfe) { - Random srand = new Random(); - testSeed = srand.nextInt(); - } - } else { - Random srand = new Random(); - testSeed = srand.nextInt(); - } - - // TestCaseNum system property - String testNumStr = System.getProperty("TestCaseNum"); - if(testNumStr != null && !testNumStr.isEmpty()) { - try { - testCaseNum = Integer.parseInt(testNumStr); - if (testCaseNum < 0 || testCaseNum > maxTestNum) { - throw new NumberFormatException(); - } - } catch(NumberFormatException nfe) { - System.out.println("Invalid TestCaseNumber property value " + - testNumStr + ". Possible value in range: 0 to " + - maxTestNum + ". Defaulting to last test case."); - testCaseNum = maxTestNum; - } - - if ( numberOfTests != -1) { - System.out.println("TestMode or NumberOfTests cannot be set along with TestCaseNum. Ignoring TestCaseNumber."); - testCaseNum = -1; - } - } - - if (numberOfTests == -1 && testCaseNum == -1) { - numberOfTests = DEFAULT_TEST_COUNT; - System.out.println("Setting TestMode to default, will run " + numberOfTests + "tests."); - } - - /* - * By this point in code, we will have: - * - testSeed: as per TestSeed or a Random one - * - numberOfTests to run or -1 to denote not set - * - testCaseNum to run or -1 to denote not set - */ - - /* - * If numberOfTests = maxTestNum, all tests are to be run, - * so no randNum will be required - */ - if (numberOfTests != -1 && numberOfTests < maxTestNum) { - System.out.println("Seed = " + testSeed); - randNum = new Random(testSeed); - uniqueTestSet = new HashSet<>(); - } - - testCompletedCount = 0; - // to be used to keep sequential count when running all tests - curTestNum = 0; - } - - /* - * returns next test case number to run - * returns -1 when there are no more tests to run - */ - public int getNextTestCase() { - if (testCaseNum != -1) { - int nextTC = testCaseNum; - testCaseNum = -1; - return nextTC; - } - if (++testCompletedCount <= numberOfTests) { - if (numberOfTests == maxTestNum) { - //all the tests need to be run, so just return - //next test case sequentially - return curTestNum++; - } else { - int nextTC = -1; - // Ensuring unique test are run - while(!uniqueTestSet.add(nextTC = randNum.nextInt(maxTestNum))) { - } - return nextTC; - } - } - return -1; - } -}
--- a/test/tools/javac/api/TestJavacTaskScanner.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/api/TestJavacTaskScanner.java Mon Mar 25 18:08:47 2013 -0700 @@ -179,7 +179,6 @@ @Override public Scanner newScanner(CharSequence input, boolean keepDocComments) { - assert !keepDocComments; if (input instanceof CharBuffer) { return new MyScanner(this, (CharBuffer)input, test); } else { @@ -190,7 +189,6 @@ @Override public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { - assert !keepDocComments; return new MyScanner(this, input, inputLength, test); }
--- a/test/tools/javac/diags/MessageFile.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/diags/MessageFile.java Mon Mar 25 18:08:47 2013 -0700 @@ -65,7 +65,7 @@ } void insertAfter(Line l) { - assert prev == null && next == null; + assert l.prev == null && l.next == null; l.prev = this; l.next = next; if (next == null) @@ -82,7 +82,7 @@ } void insertBefore(Line l) { - assert prev == null && next == null; + assert l.prev == null && l.next == null; l.prev = prev; l.next = this; if (prev == null)
--- a/test/tools/javac/diags/MessageInfo.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/diags/MessageInfo.java Mon Mar 25 18:08:47 2013 -0700 @@ -409,5 +409,3 @@ } } - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/DoubleStaticImport.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,38 @@ +/* + * 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 + * @bug 8009820 + * @summary AssertionError when compiling java code with two identical static imports + * @compile DoubleStaticImport.java + */ + +import static java.lang.Thread.holdsLock; +import static java.lang.Thread.holdsLock; //dup + +class DoubleStaticImport { + public void test() { + holdsLock(null); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/Intersection02.java Mon Mar 25 18:08:47 2013 -0700 @@ -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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8010101 + * @summary Intersection type cast issues redundant unchecked warning + * @compile/fail/ref=Intersection02.out -Werror -Xlint:unchecked -XDrawDiagnostics Intersection02.java + */ +import java.io.Serializable; +import java.util.List; + +class Intersection02 { + + interface P<X> { } + + void test(List<String> ls) { + Object o1 = (List<String> & Serializable)ls; + Object o2 = (List<String> & Serializable & P<String>)ls; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/Intersection02.out Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,4 @@ +Intersection02.java:39:62: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.util.List<java.lang.String>, java.lang.Object&java.util.List<java.lang.String>&java.io.Serializable&Intersection02.P<java.lang.String> +- compiler.err.warnings.and.werror +1 error +1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/LambdaLambdaSerialized.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,79 @@ +/* + * 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 8010010 +@summary NPE generating serializedLambdaName for nested lambda +*/ + +import java.io.*; +import java.util.Map; +import java.util.HashMap; + +public class LambdaLambdaSerialized { + + static int assertionCount = 0; + + static void assertTrue(boolean cond) { + assertionCount++; + if (!cond) + throw new AssertionError(); + } + + public static void main(String[] args) throws Exception { + try { + // Write lambdas out + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutput out = new ObjectOutputStream(baos); + LSI<LSI<Map>> ssi = () -> (() -> new HashMap()); + write(out, ssi ); + out.flush(); + out.close(); + + // Read them back + ByteArrayInputStream bais = + new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + readAssert(in, "[X]"); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + } + + static void write(ObjectOutput out, LSI<LSI<Map>> lamb) throws IOException { + out.writeObject(lamb); + } + + static void readAssert(ObjectInputStream in, String expected) throws IOException, ClassNotFoundException { + LSI<LSI<Map>> ls = (LSI<LSI<Map>>) in.readObject(); + Map result = ls.get().get(); + System.out.printf("Result: %s\n", result); + } +} + +interface LSI<T> extends Serializable { + T get(); +}
--- a/test/tools/javac/lambda/TargetType28.out Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/lambda/TargetType28.out Mon Mar 25 18:08:47 2013 -0700 @@ -1,2 +1,2 @@ -TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String,R, java.lang.Object,java.lang.Number) +TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, R,java.lang.String, java.lang.Object,java.lang.Number) 1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType67.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,50 @@ +/* + * 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 8010303 + * @summary Graph inference: missing incorporation step causes spurious inference error + * @compile TargetType67.java + */ +class TargetType67 { + + interface Func<A, B> { + B f(A a); + } + + class List<X> { + + <M> List<M> map(Func<X, M> f) { + return null; + } + + <A> List<A> apply(final List<Func<X, A>> lf) { + return null; + } + + <B, C> List<C> bind(final List<B> lb, final Func<X, Func<B, C>> f) { + return lb.apply(map(f)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType68.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,63 @@ +/* + * 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 8010303 + * @summary Graph inference: missing incorporation step causes spurious inference error + * @compile TargetType68.java + */ +import java.util.*; + +class TargetType68 { + + //derived from FX 2.2 API + static class XYChart<X,Y> { + static final class Series<X,Y> { + Series(java.lang.String name, ObservableList<XYChart.Data<X,Y>> data) { } + } + + static final class Data<X,Y> { } + + ObservableList<XYChart.Series<X,Y>> getData() { return null; } + } + + //derived from FX 2.2 API + interface ObservableList<X> extends List<X> { + boolean setAll(Collection<? extends X> col); + } + + //derived from FX 2.2 API + static class FXCollections { + static <E> ObservableList<E> observableList(List<E> l) { return null; } + } + + private void testMethod() { + XYChart<Number, Number> numberChart = null; + List<XYChart.Data<Number, Number>> data_1 = new ArrayList<>(); + List<XYChart.Data<Number, Number>> data_2 = new ArrayList<>(); + numberChart.getData().setAll( + Arrays.asList(new XYChart.Series<>("Data", FXCollections.observableList(data_1)), + new XYChart.Series<>("Data", FXCollections.observableList(data_2)))); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType69.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,51 @@ +/* + * 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 8010303 + * @summary Graph inference: missing incorporation step causes spurious inference error + * @compile TargetType68.java + */ +import java.util.*; + +class TargetType68 { + + interface Function<X,Y> { + Y m(X x); + } + + abstract class TabulationAssertion<T, U> { } + + class GroupedMapAssertion<K, M1 extends Map<K, ?>> extends TabulationAssertion<Integer, M1> { + GroupedMapAssertion(Function<Integer, K> classifier) { } + } + + + <T, M2 extends Map> void exerciseMapTabulation(Function<T, ? extends M2> collector, + TabulationAssertion<T, M2> assertion) { } + + void test(Function<Integer, Integer> classifier, Function<Integer, Map<Integer, List<Integer>>> coll) { + exerciseMapTabulation(coll, new GroupedMapAssertion<>(classifier)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/bytecode/TestLambdaBytecode.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,365 @@ +/* + * 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 8009649 + * @summary Lambda back-end should generate invokespecial for method handles referring to private instance methods + * @library ../../lib + * @build JavacTestingAbstractThreadedTest + * @run main/othervm TestLambdaBytecode + */ + +// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047) +// see JDK-8006746 + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.BootstrapMethods_attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; + +import com.sun.tools.javac.api.JavacTaskImpl; + + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; + +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; + +import static com.sun.tools.javac.jvm.ClassFile.*; + +public class TestLambdaBytecode + extends JavacTestingAbstractThreadedTest + implements Runnable { + + enum ClassKind { + CLASS("class"), + INTERFACE("interface"); + + String classStr; + + ClassKind(String classStr) { + this.classStr = classStr; + } + } + + enum AccessKind { + PUBLIC("public"), + PRIVATE("private"); + + String accessStr; + + AccessKind(String accessStr) { + this.accessStr = accessStr; + } + } + + enum StaticKind { + STATIC("static"), + INSTANCE(""); + + String staticStr; + + StaticKind(String staticStr) { + this.staticStr = staticStr; + } + } + + enum DefaultKind { + DEFAULT("default"), + NO_DEFAULT(""); + + String defaultStr; + + DefaultKind(String defaultStr) { + this.defaultStr = defaultStr; + } + } + + enum ExprKind { + LAMBDA("Runnable r = ()->{ target(); };"); + + String exprString; + + ExprKind(String exprString) { + this.exprString = exprString; + } + } + + static class MethodKind { + ClassKind ck; + AccessKind ak; + StaticKind sk; + DefaultKind dk; + + MethodKind(ClassKind ck, AccessKind ak, StaticKind sk, DefaultKind dk) { + this.ck = ck; + this.ak = ak; + this.sk = sk; + this.dk = dk; + } + + boolean inInterface() { + return ck == ClassKind.INTERFACE; + } + + boolean isPrivate() { + return ak == AccessKind.PRIVATE; + } + + boolean isStatic() { + return sk == StaticKind.STATIC; + } + + boolean isDefault() { + return dk == DefaultKind.DEFAULT; + } + + boolean isOK() { + if (isDefault() && (!inInterface() || isStatic())) { + return false; + } else if (inInterface() && + ((!isStatic() && !isDefault()) || isPrivate())) { + return false; + } else { + return true; + } + } + + String mods() { + StringBuilder buf = new StringBuilder(); + buf.append(ak.accessStr); + buf.append(' '); + buf.append(sk.staticStr); + buf.append(' '); + buf.append(dk.defaultStr); + return buf.toString(); + } + } + + public static void main(String... args) throws Exception { + for (ClassKind ck : ClassKind.values()) { + for (AccessKind ak1 : AccessKind.values()) { + for (StaticKind sk1 : StaticKind.values()) { + for (DefaultKind dk1 : DefaultKind.values()) { + for (AccessKind ak2 : AccessKind.values()) { + for (StaticKind sk2 : StaticKind.values()) { + for (DefaultKind dk2 : DefaultKind.values()) { + for (ExprKind ek : ExprKind.values()) { + pool.execute(new TestLambdaBytecode(ck, ak1, ak2, sk1, sk2, dk1, dk2, ek)); + } + } + } + } + } + } + } + } + + checkAfterExec(); + } + + MethodKind mk1, mk2; + ExprKind ek; + DiagChecker dc; + + TestLambdaBytecode(ClassKind ck, AccessKind ak1, AccessKind ak2, StaticKind sk1, + StaticKind sk2, DefaultKind dk1, DefaultKind dk2, ExprKind ek) { + mk1 = new MethodKind(ck, ak1, sk1, dk1); + mk2 = new MethodKind(ck, ak2, sk2, dk2); + this.ek = ek; + dc = new DiagChecker(); + } + + public void run() { + int id = checkCount.incrementAndGet(); + JavaSource source = new JavaSource(id); + JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc, + null, null, Arrays.asList(source)); + try { + ct.generate(); + } catch (Throwable t) { + t.printStackTrace(); + throw new AssertionError( + String.format("Error thrown when compiling following code\n%s", + source.source)); + } + if (dc.diagFound) { + boolean errorExpected = !mk1.isOK() || !mk2.isOK(); + errorExpected |= mk1.isStatic() && !mk2.isStatic(); + + if (!errorExpected) { + throw new AssertionError( + String.format("Diags found when compiling following code\n%s\n\n%s", + source.source, dc.printDiags())); + } + return; + } + verifyBytecode(id, source); + } + + void verifyBytecode(int id, JavaSource source) { + File compiledTest = new File(String.format("Test%d.class", id)); + try { + ClassFile cf = ClassFile.read(compiledTest); + Method testMethod = null; + for (Method m : cf.methods) { + if (m.getName(cf.constant_pool).equals("test")) { + testMethod = m; + break; + } + } + if (testMethod == null) { + throw new Error("Test method not found"); + } + Code_attribute ea = + (Code_attribute)testMethod.attributes.get(Attribute.Code); + if (testMethod == null) { + throw new Error("Code attribute for test() method not found"); + } + + int bsmIdx = -1; + + for (Instruction i : ea.getInstructions()) { + if (i.getMnemonic().equals("invokedynamic")) { + CONSTANT_InvokeDynamic_info indyInfo = + (CONSTANT_InvokeDynamic_info)cf + .constant_pool.get(i.getShort(1)); + bsmIdx = indyInfo.bootstrap_method_attr_index; + if (!indyInfo.getNameAndTypeInfo().getType().equals(makeIndyType(id))) { + throw new + AssertionError("type mismatch for CONSTANT_InvokeDynamic_info " + source.source + "\n" + indyInfo.getNameAndTypeInfo().getType() + "\n" + makeIndyType(id)); + } + } + } + if (bsmIdx == -1) { + throw new Error("Missing invokedynamic in generated code"); + } + + BootstrapMethods_attribute bsm_attr = + (BootstrapMethods_attribute)cf + .getAttribute(Attribute.BootstrapMethods); + if (bsm_attr.bootstrap_method_specifiers.length != 1) { + throw new Error("Bad number of method specifiers " + + "in BootstrapMethods attribute"); + } + BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec = + bsm_attr.bootstrap_method_specifiers[0]; + + if (bsm_spec.bootstrap_arguments.length != MF_ARITY) { + throw new Error("Bad number of static invokedynamic args " + + "in BootstrapMethod attribute"); + } + + CONSTANT_MethodHandle_info mh = + (CONSTANT_MethodHandle_info)cf.constant_pool.get(bsm_spec.bootstrap_arguments[1]); + + boolean kindOK; + switch (mh.reference_kind) { + case REF_invokeStatic: kindOK = mk2.isStatic(); break; + case REF_invokeSpecial: kindOK = !mk2.isStatic(); break; + case REF_invokeInterface: kindOK = mk2.inInterface(); break; + default: + kindOK = false; + } + + if (!kindOK) { + throw new Error("Bad invoke kind in implementation method handle"); + } + + if (!mh.getCPRefInfo().getNameAndTypeInfo().getType().toString().equals(MH_SIG)) { + throw new Error("Type mismatch in implementation method handle"); + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + compiledTest +": " + e); + } + } + String makeIndyType(int id) { + StringBuilder buf = new StringBuilder(); + buf.append("("); + if (!mk2.isStatic() || mk1.inInterface()) { + buf.append(String.format("LTest%d;", id)); + } + buf.append(")Ljava/lang/Runnable;"); + return buf.toString(); + } + + static final int MF_ARITY = 3; + static final String MH_SIG = "()V"; + + class JavaSource extends SimpleJavaFileObject { + + static final String source_template = + "#CK Test#ID {\n" + + " #MOD1 void test() { #EK }\n" + + " #MOD2 void target() { }\n" + + "}\n"; + + String source; + + JavaSource(int id) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = source_template.replace("#CK", mk1.ck.classStr) + .replace("#MOD1", mk1.mods()) + .replace("#MOD2", mk2.mods()) + .replace("#EK", ek.exprString) + .replace("#ID", String.valueOf(id)); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + static class DiagChecker + implements javax.tools.DiagnosticListener<JavaFileObject> { + + boolean diagFound; + ArrayList<String> diags = new ArrayList<>(); + + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { + diags.add(diagnostic.getMessage(Locale.getDefault())); + diagFound = true; + } + + String printDiags() { + StringBuilder buf = new StringBuilder(); + for (String s : diags) { + buf.append(s); + buf.append("\n"); + } + return buf.toString(); + } + } + +}
--- a/test/tools/javac/lib/ToolBox.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/lib/ToolBox.java Mon Mar 25 18:08:47 2013 -0700 @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -65,15 +66,32 @@ public static final String lineSeparator = System.getProperty("line.separator"); public static final String jdkUnderTest = System.getProperty("test.jdk"); - public static final String testVMOpts = System.getProperty("test.tool.vm.opts"); - public static final String javaBinary = Paths.get(jdkUnderTest, "bin", "java").toString(); - //why this one private. Because the function which provide also the test options should be used - private static final String javacBinary = Paths.get(jdkUnderTest, "bin", "javac").toString(); + public static final Path javaBinary = Paths.get(jdkUnderTest, "bin", "java"); + public static final Path javacBinary = Paths.get(jdkUnderTest, "bin", "javac"); + + public static final List<String> testToolVMOpts; + public static final List<String> testVMOpts; private static final Charset defaultCharset = Charset.defaultCharset(); static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + static { + String sysProp = System.getProperty("test.tool.vm.opts"); + if (sysProp != null && sysProp.length() > 0) { + testToolVMOpts = Arrays.asList(sysProp.split("\\s+")); + } else { + testToolVMOpts = Collections.<String>emptyList(); + } + + sysProp = System.getProperty("test.vm.opts"); + if (sysProp != null && sysProp.length() > 0) { + testVMOpts = Arrays.asList(sysProp.split("\\s+")); + } else { + testVMOpts = Collections.<String>emptyList(); + } + } + /** * The expected result of command-like method execution. */ @@ -199,8 +217,8 @@ protected Expect whatToExpect; protected WriterHelper stdOutput; protected WriterHelper errOutput; - protected List<String> options; - protected String[] optionsArr; + protected List<String> args = new ArrayList<>(); + protected String[] argsArr; protected GenericArgs() { set(Expect.SUCCESS); @@ -238,19 +256,50 @@ public T setAllArgs(String... args) { currentParams.add(AcceptedParams.OPTIONS); - this.optionsArr = args; + this.argsArr = args; + return (T) this; + } + + + public T appendArgs(String... args) { + appendArgs(Arrays.asList(args)); + return (T)this; + } + + public T appendArgs(Path... args) { + if (args != null) { + List<String> list = new ArrayList<>(); + for (int i = 0; i < args.length; i++) { + if (args[i] != null) { + list.add(args[i].toString()); + } + } + appendArgs(list); + } + return (T)this; + } + + public T appendArgs(List<String> args) { + if (args != null && args.size() > 0) { + currentParams.add(AcceptedParams.OPTIONS); + for (int i = 0; i < args.size(); i++) { + if (args.get(i) != null) { + this.args.add(args.get(i)); + } + } + } return (T)this; } public T setOptions(List<String> options) { currentParams.add(AcceptedParams.OPTIONS); - this.options = options; + this.args = options; return (T)this; } public T setOptions(String... options) { currentParams.add(AcceptedParams.OPTIONS); - this.options = Arrays.asList(options); + this.args = Arrays.asList(options); return (T)this; } @@ -365,8 +414,12 @@ * Custom exception for not equal resources. */ public static class ResourcesNotEqualException extends Exception { - public ResourcesNotEqualException() { - super("The resources provided for comparison are different"); + public ResourcesNotEqualException(List<String> res1, List<String> res2) { + super(createMessage(res1, res2)); + } + + public ResourcesNotEqualException(String line1, String line2) { + super(createMessage(line1, line2)); } public ResourcesNotEqualException(Path path1, Path path2) { @@ -379,15 +432,20 @@ .append(path1.toString()).append(" and \n") .append(path2.toString()).append("are different").toString(); } - } - /** - * Method to get the a path to the javac command available at the jdk being - * tested along with the test vm options. - * @return a String[] with the two components mentioned. - */ - public static String[] getJavacBin() { - return new String[]{javacBinary, testVMOpts}; + private static String createMessage(String line1, String line2) { + return new StringBuilder() + .append("The resources provided for comparison are different at lines: \n") + .append(line1).append(" and \n") + .append(line2).toString(); + } + + private static String createMessage(List<String> res1, List<String> res2) { + return new StringBuilder() + .append("The resources provided for comparison are different: \n") + .append("Resource 1 is: ").append(res1).append("\n and \n") + .append("Resource 2 is: ").append(res2).append("\n").toString(); + } } /** @@ -396,7 +454,7 @@ public static int javac(JavaToolArgs params) throws CommandExecutionException, IOException { if (params.hasMinParams()) { - if (params.optionsArr != null) { + if (params.argsArr != null) { return genericJavaCMD(JavaCMD.JAVAC, params); } else { return genericJavaCMD(JavaCMD.JAVAC_API, params); @@ -437,14 +495,14 @@ JAVAC { @Override int run(JavaToolArgs params, PrintWriter pw) { - return com.sun.tools.javac.Main.compile(params.optionsArr, pw); + return com.sun.tools.javac.Main.compile(params.argsArr, pw); } }, JAVAC_API { @Override int run(JavaToolArgs params, PrintWriter pw) { JavacTask ct = (JavacTask)comp.getTask(pw, null, null, - params.options, null, params.sources); + params.args, null, params.sources); return ((JavacTaskImpl)ct).doCall().exitCode; } @@ -467,13 +525,13 @@ JAVAH { @Override int run(JavaToolArgs params, PrintWriter pw) { - return com.sun.tools.javah.Main.run(params.optionsArr, pw); + return com.sun.tools.javah.Main.run(params.argsArr, pw); } }, JAVAP { @Override int run(JavaToolArgs params, PrintWriter pw) { - return com.sun.tools.javap.Main.run(params.optionsArr, pw); + return com.sun.tools.javap.Main.run(params.argsArr, pw); } }; @@ -486,9 +544,9 @@ List<String> getExceptionMsgContent(JavaToolArgs params) { List<String> result = new ArrayList<>(); result.add(getName()); - result.addAll(params.optionsArr != null ? - Arrays.asList(params.optionsArr) : - params.options); + result.addAll(params.argsArr != null ? + Arrays.asList(params.argsArr) : + params.args); return result; } } @@ -509,7 +567,7 @@ String out = (sw == null) ? null : sw.toString(); if (params.errOutput != null && (out != null) && !out.isEmpty()) { - params.errOutput.addAll(splitLines(out)); + params.errOutput.addAll(splitLines(out, lineSeparator)); } if ( (rc == 0 && params.whatToExpect == Expect.SUCCESS) || @@ -542,9 +600,9 @@ public static int executeCommand(AnyToolArgs params) throws CommandExecutionException, IOException, InterruptedException { if (params.hasMinParams()) { - List<String> cmd = (params.options != null) ? - params.options : - Arrays.asList(params.optionsArr); + List<String> cmd = (params.args != null) ? + params.args : + Arrays.asList(params.argsArr); return executeCommand(cmd, params.extraEnv, params.stdOutput, params.errOutput, params.whatToExpect); } @@ -630,7 +688,7 @@ List<String> list2, boolean trim) throws ResourcesNotEqualException { if ((list1 == list2) || (list1 == null && list2 == null)) return; if (list1.size() != list2.size()) - throw new ResourcesNotEqualException(); + throw new ResourcesNotEqualException(list1, list2); int i = 0; int j = 0; while (i < list1.size() && @@ -639,7 +697,7 @@ i++; j++; } if (!(i == list1.size() && j == list2.size())) - throw new ResourcesNotEqualException(); + throw new ResourcesNotEqualException(list1, list2); } private static boolean equals(String s1, String s2, boolean trim) { @@ -652,8 +710,8 @@ * and later the regExpr is seek in every split line. If a match is found, * the whole line is added to the result. */ - public static List<String> grep(String regExpr, String text) { - return grep(regExpr, splitLines(text)); + public static List<String> grep(String regExpr, String text, String sep) { + return grep(regExpr, splitLines(text, sep)); } public static List<String> grep(String regExpr, List<String> text) { @@ -865,8 +923,8 @@ /** * Splits a String using the System's line separator character as splitting point. */ - public static List<String> splitLines(String lines) { - return Arrays.asList(lines.split(lineSeparator)); + public static List<String> splitLines(String lines, String sep) { + return Arrays.asList(lines.split(sep)); } /** @@ -882,6 +940,14 @@ } /** + * Returns true if the OS is a Windows version. + */ + public static boolean isWindows() { + String osName = System.getProperty("os.name"); + return osName.toUpperCase().startsWith("WINDOWS"); + } + + /** * Class representing an in-memory java source file. It is able to extract * the file name from simple source codes using regular expressions. */
--- a/test/tools/javac/links/LinksTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/links/LinksTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -50,14 +50,17 @@ // cp ${TESTSRC}/b/B.java tmp ToolBox.writeFile(Paths.get("tmp", "B.java"), BSrc); + try { // ln -s `pwd`/tmp "${TESTCLASSES}/a" - Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp")); -// -////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1 - ToolBox.JavaToolArgs javacArgs = - new ToolBox.JavaToolArgs() - .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc); - ToolBox.javac(javacArgs); + Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp")); + ////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1 + ToolBox.JavaToolArgs javacArgs = + new ToolBox.JavaToolArgs() + .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc); + ToolBox.javac(javacArgs); + } catch (UnsupportedOperationException e) { + System.err.println("Symbolic links not supported on this system. The test can't finish"); + } } }
--- a/test/tools/javac/newlines/NewLineTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/newlines/NewLineTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -34,19 +34,18 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.util.List; -import com.sun.tools.javac.util.ArrayUtils; //original test: test/tools/javac/newlines/Newlines.sh public class NewLineTest { public static void main(String args[]) throws Exception { - String[] mainArgs = ToolBox.getJavacBin(); - // "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -J-Dline.separator='@' > ${TMP1} 2>&1 File javacErrOutput = new File("output.txt"); ToolBox.AnyToolArgs cmdArgs = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) - .setAllArgs(ArrayUtils.concatOpen(mainArgs, "-J-Dline.separator='@'")) + .appendArgs(ToolBox.javacBinary) + .appendArgs(ToolBox.testToolVMOpts) + .appendArgs("-J-Dline.separator='@'") .setErrOutput(javacErrOutput); ToolBox.executeCommand(cmdArgs);
--- a/test/tools/javac/profiles/ProfileOptionTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javac/profiles/ProfileOptionTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -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 @@ -106,7 +106,6 @@ for (Target t: Target.values()) { switch (t) { case JDK1_1: case JDK1_2: // no equivalent -source - case JDK1_4_1: case JDK1_4_2: case JSR14: // transitional values continue; }
--- a/test/tools/javah/6257087/T6257087.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javah/6257087/T6257087.java Mon Mar 25 18:08:47 2013 -0700 @@ -32,7 +32,6 @@ import java.nio.file.Paths; -//original test: test/tools/javah/6257087/foo.sh public class T6257087 { private static final String fooBarGoldenFile = @@ -59,17 +58,13 @@ "#endif"; public static void main(String[] args) throws Exception { -// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d "${TC}" "${TS}${FS}foo.java" - -// "${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} -classpath "${TC}" -d "${TC}" foo ToolBox.JavaToolArgs javahArgs = new ToolBox.JavaToolArgs() .setAllArgs("-cp", System.getProperty("test.classes"), "foo"); ToolBox.javah(javahArgs); -// diff ${DIFFOPTS} -c "${TS}${FS}foo_bar.h" "${TC}${FS}foo_bar.h" ToolBox.compareLines(Paths.get("foo_bar.h"), - ToolBox.splitLines(fooBarGoldenFile), null); + ToolBox.splitLines(fooBarGoldenFile, "\n"), null, true); } }
--- a/test/tools/javah/constMacroTest/ConstMacroTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javah/constMacroTest/ConstMacroTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -38,7 +38,7 @@ //original test: test/tools/javah/ConstMacroTest.sh public class ConstMacroTest { - private static final String SubClassConstsGoldenFile = + private static final String subClassConstsGoldenFileTemplate = "/* DO NOT EDIT THIS FILE - it is machine generated */\n" + "#include <jni.h>\n" + "/* Header for class SubClassConsts */\n" + @@ -49,7 +49,7 @@ "extern \"C\" {\n" + "#endif\n" + "#undef SubClassConsts_serialVersionUID\n" + - "#define SubClassConsts_serialVersionUID 6733861379283244755LL\n" + + "#define SubClassConsts_serialVersionUID 6733861379283244755%s\n" + "#undef SubClassConsts_SUPER_INT_CONSTANT\n" + "#define SubClassConsts_SUPER_INT_CONSTANT 3L\n" + "#undef SubClassConsts_SUPER_FLOAT_CONSTANT\n" + @@ -71,6 +71,9 @@ "#endif\n" + "#endif"; + private static final String serialVersionUIDSuffix = + ToolBox.isWindows() ? "i64" : "LL"; ; + public static void main(String[] args) throws Exception { //first steps are now done by jtreg // cp "${TESTSRC}${FS}SuperClassConsts.java" . @@ -85,8 +88,10 @@ ToolBox.javah(successParams); // diff ${DIFFOPTS} "${TESTSRC}${FS}${EXPECTED_JAVAH_OUT_FILE}" "${GENERATED_HEADER_FILE}" + String subClassConstGoldenFile = String.format(subClassConstsGoldenFileTemplate, + serialVersionUIDSuffix); ToolBox.compareLines(Paths.get("SubClassConsts.h"), - ToolBox.splitLines(SubClassConstsGoldenFile), null); + ToolBox.splitLines(subClassConstGoldenFile, "\n"), null, true); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/output/RepeatingTypeAnnotations.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,400 @@ +/* + * 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 8005220 + * @summary javap must display repeating annotations + */ +import java.io.*; +import java.util.*; + +/** + * This class extends the abstract {@link Tester} test-driver, and + * encapusulates a number of test-case classes (i.e. classes extending + * this class and annotated with {@code TestCase}). + * <p> + * By default (no argument), this test runs all test-cases, except + * if annotated with {@code ignore}. + * <p> + * Individual test cases can be executed using a run action. + * <p> + * Example: @run main RepeatingTypeAnnotations RepeatingTypeAnnotations$TC4 + * <p> + * Note: when specific test-cases are run, additional debug output is + * produced to help debugging. Test annotated with {@code ignore} + * can be executed explicitly. + */ +public class RepeatingTypeAnnotations extends Tester { + + /** + * Main method instantiates test and run test-cases. + */ + public static void main(String... args) throws Exception { + Tester tester = new RepeatingTypeAnnotations(); + tester.run(args); + } + + /** + * Testcases are classes extending {@code RepeatingTypeAnnotations}, + * and calling {@link setSrc}, followed by one or more invocations + * of {@link verify} in the body of the constructor. + */ + public RepeatingTypeAnnotations() { + setSrc(new TestSource(template)); + } + + /** + * Common template for test cases. The line TESTCASE is + * replaced with the specific lines of individual tests. + */ + private static final String[] template = { + "import java.lang.annotation.*;", + "class Test {", + " @Repeatable(As.class)", + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.CLASS)", + " @interface A {", + " Class f() default int.class;", + " }", + + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.CLASS)", + " @interface As { A[] value(); }", + + " @Repeatable(Bs.class)", + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.CLASS)", + " @interface B {", + " Class f() default int.class;", + " }", + + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.CLASS)", + " @interface Bs { B[] value(); }", + + " @Repeatable(Cs.class)", + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.RUNTIME)", + " @interface C {", + " Class f() default int.class;", + " }", + + " @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})", + " @Retention(RetentionPolicy.RUNTIME)", + " @interface Cs { C[] value(); }", + "TESTCASE", + "}" + }; + + /* + * The test cases covers annotation in the following locations: + * - static and non-static fields + * - local variables + * - constructor and method return type and parameter types + * - casts in class and method contexts. + * For the above locations the test-cases covers: + * - single annotation type + * - two annotation types with same retention + * - two annotation types with different retention + * - three annotation types, two of same retention, one different. + */ + + @TestCase + @ignore // 8008082:missing type annotation for cast + public static class TC1 extends RepeatingTypeAnnotations { + public TC1() { + setSrc(" static String so = \"hello world\";", + " public @A @A @A Object o = (@A @A @A String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD", + "1: #25(#26=[@#27(),@#27(),@#27()]): CAST, offset=5"); + } + } + + @TestCase + public static class TC2 extends RepeatingTypeAnnotations { + public TC2() { + setSrc(" static String so = \"hello world\";", + " public @A @B @A Object o = (@B @A @B String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #25(#26=[@#27(),@#27()]): FIELD", + "1: #28(): FIELD", + "2: #29(#26=[@#28(),@#28()]): CAST, offset=5", + "3: #27(): CAST, offset=5"); + } + } + + @TestCase + public static class TC3 extends RepeatingTypeAnnotations { + public TC3() { + setSrc(" static String so = \"hello world\";", + " public @A @A @C Object o = (@B @C @B String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #25(): FIELD", + "1: #25(): CAST, offset=5", + "RuntimeVisibleTypeAnnotations", + "0: #27(#28=[@#29(),@#29()]): FIELD", + "1: #30(#28=[@#31(),@#31()]): CAST, offset=5"); + } + } + + @TestCase + public static class TC4 extends RepeatingTypeAnnotations { + public TC4() { + setSrc(" static String so = \"hello world\";", + " public @A @B @C Object o = (@C @B @A String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #25(): FIELD", + "1: #25(): CAST, offset=5", + "0: #27(): FIELD", + "1: #28(): FIELD", + "2: #28(): CAST, offset=5", + "3: #27(): CAST, offset=5"); + } + } + + @TestCase + @ignore // 8008082:missing type annotation for cast + public static class TC5 extends RepeatingTypeAnnotations { + public TC5() { + setSrc(" static String so = \"hello world\";", + " public static @A @A @A Object o = (@B @B @B String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #25(#26=[@#27(),@#27(),@#27()]): FIELD", + "1: #28(#26=[@#29(),@#29(),@#29()]): CAST, offset=5, type_index=0"); + } + } + + @TestCase + public static class TC6 extends RepeatingTypeAnnotations { + public TC6() { + setSrc(" static String so = \"hello world\";", + " public static @A @B @A Object o = (@B @A @B String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #25(#26=[@#27(),@#27()]): FIELD", + "1: #28(): FIELD", + "2: #29(#26=[@#28(),@#28()]): CAST, offset=5", + "3: #27(): CAST, offset=5"); + } + } + + @TestCase + public static class TC7 extends RepeatingTypeAnnotations { + public TC7() { + setSrc(" static String so = \"hello world\";", + " public static @A @A @C Object o = (@B @C @B String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #25(): FIELD", + "1: #25(): CAST, offset=5", + "0: #27(#28=[@#29(),@#29()]): FIELD", + "1: #30(#28=[@#31(),@#31()]): CAST, offset=5"); + } + } + + @TestCase + public static class TC8 extends RepeatingTypeAnnotations { + public TC8() { + setSrc(" static String so = \"hello world\";", + " public static @A @B @C Object o = (@C @B @A String) Test.so;"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #25(): FIELD", + "1: #25(): CAST, offset=5", + "0: #27(): FIELD", + "1: #28(): FIELD", + "2: #28(): CAST, offset=5", + "3: #27(): CAST, offset=5"); + } + } + + @TestCase + @ignore // 8008082:missing type annotation for cast + public static class TC9 extends RepeatingTypeAnnotations { + public TC9() { + setSrc(" public Test(@A @A @A Object o, @A int i, long l) {", + " @A @A @A String ls = (@B @B @B String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #34(#35=[@#36(),@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #36(): METHOD_FORMAL_PARAMETER, param_index=1", + "2: #37(#35=[@#38(),@#38(),@#38()]): CAST, offset=4, type_index=0", + "3: #34(#35=[@#36(),@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}"); + } + } + + @TestCase + public static class TC10 extends RepeatingTypeAnnotations { + public TC10() { + setSrc(" public Test(@A @A @B Object o, @A @B int i, long l) {", + " @A @A @B String ls = (@B @A @B String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations:", + "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #37(): METHOD_FORMAL_PARAMETER, param_index=1", + "4: #38(#35=[@#37(),@#37()]): CAST, offset=4, type_index=0", + "5: #36(): CAST, offset=4, type_index=0", + "6: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}", + "7: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}"); + } + } + + @TestCase + public static class TC11 extends RepeatingTypeAnnotations { + public TC11() { + setSrc(" public Test(@C @C @A Object o, @A @B int i, long l) {", + " @C @C @A String ls = (@A @A @C String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #34(#35=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #36(): CAST, offset=4", + "2: #34(#35=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}", + "0: #38(): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #38(): METHOD_FORMAL_PARAMETER, param_index=1", + "2: #39(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #40(#35=[@#38(),@#38()]): CAST, offset=4", + "4: #38(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}"); + } + } + + @TestCase + public static class TC12 extends RepeatingTypeAnnotations { + public TC12() { + setSrc(" public Test(@A @B @C Object o, @A @C int i, long l) {", + " @A @B @C String ls = (@C @A @B String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #34(): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #34(): METHOD_FORMAL_PARAMETER, param_index=1", + "2: #34(): CAST, offset=4", + "3: #34(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}", + "0: #36(): METHOD_FORMAL_PARAMETER, param_index=0", + "1: #37(): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #36(): CAST, offset=4", + "4: #37(): CAST, offset=4", + "5: #36(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}", + "6: #37(): LOCAL_VARIABLE, {start_pc=10, length=1, index=5}"); + } + } + + @TestCase + @ignore // 8008082:missing type annotation for cast + public static class TC13 extends RepeatingTypeAnnotations { + public TC13() { + setSrc(" public @A @A @A String foo(@A @A @A Object o, @A int i, long l) {", + " @A @A @A String ls = (@B @B @B String) o;", + " return (@A @A @A String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #36(#37=[@#38(),@#38(),@#38()]): METHOD_RETURN", + "1: #36(#37=[@#38(),@#38(),@#38()]): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #38(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #39(#37=[@#40(),@#40(),@#40()]): CAST, offset=0, type_index=0", + "4: #36(#37=[@#38(),@#38(),@#38()]): CAST, offset=6, type_index=0", + "5: #36(#37=[@#38(),@#38(),@#38()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}"); + } + } + + @TestCase + public static class TC14 extends RepeatingTypeAnnotations { + public TC14() { + setSrc(" public @A @B @B String foo(@A @A @B Object o, @A @B int i, long l) {", + " @A @A @B String ls = (@B @A @B String) o;", + " return (@A @B @B String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "0: #36(): METHOD_RETURN", + "1: #37(#38=[@#39(),@#39()]): METHOD_RETURN", + "2: #40(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0", + "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0", + "4: #36(): METHOD_FORMAL_PARAMETER, param_index=1", + "5: #39(): METHOD_FORMAL_PARAMETER, param_index=1", + "6: #37(#38=[@#39(),@#39()]): CAST, offset=0", + "7: #36(): CAST, offset=0", + "8: #36(): CAST, offset=6", + "9: #37(#38=[@#39(),@#39()]): CAST, offset=6", + "10: #40(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}", + "11: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}"); + } + } + + @TestCase + public static class TC15 extends RepeatingTypeAnnotations { + public TC15() { + setSrc(" public @A @A @C String foo(@C @C @A Object o, @A @B int i, long l) {", + " @C @C @A String ls = (@A @A @C String) o;", + " return (@C @B @B String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #36(): METHOD_RETURN", + "1: #37(#38=[@#36(),@#36()]): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #36(): CAST, offset=0", + "3: #36(): CAST, offset=6", + "4: #37(#38=[@#36(),@#36()]): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}", + "0: #40(#38=[@#41(),@#41()]): METHOD_RETURN", + "1: #41(): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #41(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #42(): METHOD_FORMAL_PARAMETER, param_index=1", + "4: #40(#38=[@#41(),@#41()]): CAST, offset=0", + "5: #43(#38=[@#42(),@#42()]): CAST, offset=6", + "6: #41(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}"); + } + } + + @TestCase + public static class TC16 extends RepeatingTypeAnnotations { + public TC16() { + setSrc(" public @A @B @C String foo(@A @B @C Object o, @A @C int i, long l) {", + " @A @B @C String ls = (@C @A @B String) o;", + " return (@B @A @C String) o;", + " }"); + verify("RuntimeInvisibleTypeAnnotations", + "RuntimeVisibleTypeAnnotations", + "0: #36(): METHOD_RETURN", + "1: #36(): METHOD_FORMAL_PARAMETER, param_index=0", + "2: #36(): METHOD_FORMAL_PARAMETER, param_index=1", + "3: #36(): CAST, offset=0", + "4: #36(): CAST, offset=6", + "5: #36(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}", + "0: #38(): METHOD_RETURN", + "1: #39(): METHOD_RETURN", + "2: #38(): METHOD_FORMAL_PARAMETER, param_index=0", + "3: #39(): METHOD_FORMAL_PARAMETER, param_index=0", + "4: #38(): METHOD_FORMAL_PARAMETER, param_index=1", + "5: #38(): CAST, offset=0", + "6: #39(): CAST, offset=0", + "7: #39(): CAST, offset=6", + "8: #38(): CAST, offset=6", + "9: #38(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}", + "10: #39(): LOCAL_VARIABLE, {start_pc=6, length=5, index=5}"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/output/Tester.java Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,389 @@ +/* + * 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.io.*; +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.InvocationTargetException; + +/** + * {@code Tester} is an abstract test-driver that provides the logic + * to execute test-cases, grouped by test classes. + * A test class is a main class extending this class, that instantiate + * itself, and calls the {@link run} method, passing any command line + * arguments. + * <p> + * The {@code run} method, expects arguments to identify test-case classes. + * A test-case class is a class extending the test class, and annotated + * with {@code TestCase}. + * <p> + * If no test-cases are specified, the test class directory is searched for + * co-located test-case classes (i.e. any class extending the test class, + * annotated with {@code TestCase}). + * <p> + * Besides serving to group test-cases, extending the driver allow + * setting up a test-case template, and possibly overwrite default + * test-driver behaviour. + */ +public abstract class Tester { + + private static boolean debug = false; + private static final PrintStream out = System.err; + private static final PrintStream err = System.err; + + + protected void run(String... args) throws Exception { + + final File classesdir = new File(System.getProperty("test.classes", ".")); + + String[] classNames = args; + + // If no test-cases are specified, we regard all co-located classes + // as potential test-cases. + if (args.length == 0) { + final String pattern = ".*\\.class"; + final File classFiles[] = classesdir.listFiles(new FileFilter() { + public boolean accept(File f) { + return f.getName().matches(pattern); + } + }); + ArrayList<String> names = new ArrayList<String>(classFiles.length); + for (File f : classFiles) { + String fname = f.getName(); + names.add(fname.substring(0, fname.length() -6)); + } + classNames = names.toArray(new String[names.size()]); + } else { + debug = true; + } + // Test-cases must extend the driver type, and be marked + // @TestCase. Other arguments (classes) are ignored. + // Test-cases are instantiated, and thereby executed. + for (String clname : classNames) { + try { + final Class tclass = Class.forName(clname); + if (!getClass().isAssignableFrom(tclass)) continue; + TestCase anno = (TestCase) tclass.getAnnotation(TestCase.class); + if (anno == null) continue; + if (!debug) { + ignore i = (ignore) tclass.getAnnotation(ignore.class); + if (i != null) { + out.println("Ignore: " + clname); + ignored++; + continue; + } + } + out.println("TestCase: " + clname); + cases++; + Tester tc = (Tester) tclass.getConstructor().newInstance(); + if (tc.errors > 0) { + error("" + tc.errors + " test points failed in " + clname); + errors += tc.errors - 1; + fcases++; + } + } catch(ReflectiveOperationException roe) { + error("Warning: " + clname + " - ReflectiveOperationException"); + roe.printStackTrace(err); + } catch(Exception unknown) { + error("Warning: " + clname + " - uncaught exception"); + unknown.printStackTrace(err); + } + } + + String imsg = ignored > 0 ? " (" + ignored + " ignored)" : ""; + if (errors > 0) + throw new Error(errors + " error, in " + fcases + " of " + cases + " test-cases" + imsg); + else + err.println("" + cases + " test-cases executed" + imsg + ", no errors"); + } + + + /** + * Test-cases must be marked with the {@code TestCase} annotation, + * as well as extend {@code Tester} (or an driver extension + * specified as the first argument to the {@code main()} method. + */ + @Retention(RetentionPolicy.RUNTIME) + @interface TestCase { } + + /** + * Individual test-cases failing due to product bugs, may temporarily + * be excluded by marking them like this: + * @ignore // 1234567:bug synopsis + */ + @Retention(RetentionPolicy.RUNTIME) + @interface ignore { } + + /** + * Test-cases are classes extending {@code Tester}, and + * calling {@link setSrc}, followed by one or more invocations + * of {@link verify} in the body of the constructor. + * <p> + * Sets a default test-case template, which is empty except + * for a key of {@code "TESTCASE"}. + * Subclasses will typically call {@code setSrc(TestSource)} + * to setup a useful test-case template. + */ + public Tester() { + this.testCase = this.getClass().getName(); + src = new TestSource("TESTCASE"); + } + + /** + * Set the top-level source template. + */ + protected Tester setSrc(TestSource src) { + this.src = src; + return this; + } + + /** + * Convenience method for calling {@code innerSrc("TESTCASE", ...)}. + */ + protected Tester setSrc(String... lines) { + return innerSrc("TESTCASE", lines); + } + + /** + * Convenience method for calling {@code innerSrc(key, new TestSource(...))}. + */ + protected Tester innerSrc(String key, String... lines) { + return innerSrc(key, new TestSource(lines)); + } + + /** + * Specialize the testcase template, setting replacement content + * for the specified key. + */ + protected Tester innerSrc(String key, TestSource content) { + if (src == null) { + src = new TestSource(key); + } + src.setInner(key, content); + return this; + } + + /** + * On the first invocation, call {@code execute()} to compile + * the test-case source and process the resulting class(se) + * into verifiable output. + * <p> + * Verify that the output matches each of the regular expressions + * given as argument. + * <p> + * Any failure to match constitutes a test failure, but doesn't + * abort the test-case. + * <p> + * Any exception (e.g. bad regular expression syntax) results in + * a test failure, and aborts the test-case. + */ + protected void verify(String... expect) { + if (!didExecute) { + try { + execute(); + } catch(Exception ue) { + throw new Error(ue); + } finally { + didExecute = true; + } + } + if (output == null) { + error("output is null"); + return; + } + for (String e: expect) { + // Escape regular expressions (to allow input to be literals). + // Notice, characters to be escaped are themselves identified + // using regular expressions + String rc[] = { "(", ")", "[", "]", "{", "}", "$" }; + for (String c : rc) { + e = e.replace(c, "\\" + c); + } + // DEBUG: Uncomment this to test modulo constant pool index. + // e = e.replaceAll("#[0-9]{2}", "#[0-9]{2}"); + if (!output.matches("(?s).*" + e + ".*")) { + if (!didPrint) { + out.println(output); + didPrint = true; + } + error("not matched: '" + e + "'"); + } else if(debug) { + out.println("matched: '" + e + "'"); + } + } + } + + /** + * Calls {@code writeTestFile()} to write out the test-case source + * content to a file, then call {@code compileTestFile()} to + * compile it, and finally run the {@link process} method to produce + * verifiable output. The default {@code process} method runs javap. + * <p> + * If an exception occurs, it results in a test failure, and + * aborts the test-case. + */ + protected void execute() throws IOException { + err.println("TestCase: " + testCase); + writeTestFile(); + compileTestFile(); + process(); + } + + /** + * Generate java source from test-case. + * TBD: change to use javaFileObject, possibly make + * this class extend JavaFileObject. + */ + protected void writeTestFile() throws IOException { + javaFile = new File("Test.java"); + FileWriter fw = new FileWriter(javaFile); + BufferedWriter bw = new BufferedWriter(fw); + PrintWriter pw = new PrintWriter(bw); + for (String line : src) { + pw.println(line); + if (debug) out.println(line); + } + pw.close(); + } + + /** + * Compile the Java source code. + */ + protected void compileTestFile() { + String path = javaFile.getPath(); + String params[] = { "-source", "1.8", "-g", path }; + int rc = com.sun.tools.javac.Main.compile(params); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + classFile = new File(path.substring(0, path.length() - 5) + ".class"); + } + + + /** + * Process class file to generate output for verification. + * The default implementation simply runs javap. This might be + * overwritten to generate output in a different manner. + */ + protected void process() { + String testClasses = "."; //System.getProperty("test.classes", "."); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { "-v", "-classpath", testClasses, "Test" }; + int rc = com.sun.tools.javap.Main.run(args, pw); + if (rc != 0) + throw new Error("javap failed. rc=" + rc); + pw.close(); + output = sw.toString(); + if (debug) { + out.println(output); + didPrint = true; + } + + } + + + private String testCase; + private TestSource src; + private File javaFile = null; + private File classFile = null; + private String output = null; + private boolean didExecute = false; + private boolean didPrint = false; + + + protected void error(String msg) { + err.println("Error: " + msg); + errors++; + } + + private int cases; + private int fcases; + private int errors; + private int ignored; + + /** + * The TestSource class provides a simple container for + * test cases. It contains an array of source code lines, + * where zero or more lines may be markers for nested lines. + * This allows representing templates, with specialization. + * <P> + * This may be generalized to support more advance combo + * tests, but presently it's only used with a static template, + * and one level of specialization. + */ + public class TestSource implements Iterable<String> { + + private String[] lines; + private Hashtable<String, TestSource> innerSrc; + + public TestSource(String... lines) { + this.lines = lines; + innerSrc = new Hashtable<String, TestSource>(); + } + + public void setInner(String key, TestSource inner) { + innerSrc.put(key, inner); + } + + public void setInner(String key, String... lines) { + innerSrc.put(key, new TestSource(lines)); + } + + public Iterator<String> iterator() { + return new LineIterator(); + } + + private class LineIterator implements Iterator<String> { + + int nextLine = 0; + Iterator<String> innerIt = null; + + public boolean hasNext() { + return nextLine < lines.length; + } + + public String next() { + if (!hasNext()) throw new NoSuchElementException(); + String str = lines[nextLine]; + TestSource inner = innerSrc.get(str); + if (inner == null) { + nextLine++; + return str; + } + if (innerIt == null) { + innerIt = inner.iterator(); + } + if (innerIt.hasNext()) { + return innerIt.next(); + } + innerIt = null; + nextLine++; + return next(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + } +}
--- a/test/tools/javap/stackmap/StackmapTest.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/javap/stackmap/StackmapTest.java Mon Mar 25 18:08:47 2013 -0700 @@ -84,10 +84,11 @@ new ToolBox.JavaToolArgs() .setAllArgs("-v", "Test.class"); String out = ToolBox.javap(javapParams); - List<String> grepResult = ToolBox.grep("frame_type", out); - grepResult.addAll(ToolBox.grep("offset_delta", out)); - grepResult.addAll(ToolBox.grep("stack = ", out)); - grepResult.addAll(ToolBox.grep("locals = ", out)); + List<String> grepResult = ToolBox.grep("frame_type", out, + ToolBox.lineSeparator); + grepResult.addAll(ToolBox.grep("offset_delta", out, ToolBox.lineSeparator)); + grepResult.addAll(ToolBox.grep("stack = ", out, ToolBox.lineSeparator)); + grepResult.addAll(ToolBox.grep("locals = ", out, ToolBox.lineSeparator)); List<String> goldenList = Arrays.asList(goldenOut.split("\n")); // diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
--- a/test/tools/jdeps/Basic.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/jdeps/Basic.java Mon Mar 25 18:08:47 2013 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 8003562 + * @bug 8003562 8005428 * @summary Basic tests for jdeps tool * @build Test p.Foo * @run main Basic @@ -33,13 +33,35 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; import java.util.regex.*; public class Basic { + private static boolean symbolFileExist = initProfiles(); + private static boolean initProfiles() { + // check if ct.sym exists; if not use the profiles.properties file + Path home = Paths.get(System.getProperty("java.home")); + if (home.endsWith("jre")) { + home = home.getParent(); + } + Path ctsym = home.resolve("lib").resolve("ct.sym"); + boolean symbolExists = ctsym.toFile().exists(); + if (!symbolExists) { + Path testSrcProfiles = + Paths.get(System.getProperty("test.src", "."), "profiles.properties"); + if (!testSrcProfiles.toFile().exists()) + throw new Error(testSrcProfiles + " does not exist"); + System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n", + ctsym, testSrcProfiles); + System.setProperty("jdeps.profiles", testSrcProfiles.toString()); + } + return symbolExists; + } + public static void main(String... args) throws Exception { int errors = 0; - errors += new Basic().run(); if (errors > 0) throw new Exception(errors + " errors found"); @@ -49,54 +71,70 @@ File testDir = new File(System.getProperty("test.classes", ".")); // test a .class file test(new File(testDir, "Test.class"), - new String[] {"java.lang", "p"}); + new String[] {"java.lang", "p"}, + new String[] {"compact1", "not found"}); // test a directory test(new File(testDir, "p"), - new String[] {"java.lang", "java.util"}); + new String[] {"java.lang", "java.util", "java.lang.management"}, + new String[] {"compact1", "compact1", "compact3"}); // test class-level dependency output test(new File(testDir, "Test.class"), new String[] {"java.lang.Object", "p.Foo"}, + new String[] {"compact1", "not found"}, new String[] {"-V", "class"}); // test -p option test(new File(testDir, "Test.class"), new String[] {"p.Foo"}, + new String[] {"not found"}, new String[] {"--verbose-level=class", "-p", "p"}); // test -e option test(new File(testDir, "Test.class"), new String[] {"p.Foo"}, + new String[] {"not found"}, new String[] {"-V", "class", "-e", "p\\..*"}); test(new File(testDir, "Test.class"), new String[] {"java.lang"}, + new String[] {"compact1"}, new String[] {"-V", "package", "-e", "java\\.lang\\..*"}); // test -classpath and wildcard options test(null, new String[] {"com.sun.tools.jdeps", "java.lang", "java.util", - "java.util.regex", "java.io"}, + "java.util.regex", "java.io", "java.nio.file", + "java.lang.management"}, + new String[] {(symbolFileExist? "not found" : "JDK internal API (classes)"), + "compact1", "compact1", "compact1", + "compact1", "compact1", "compact3"}, new String[] {"--classpath", testDir.getPath(), "*"}); - // -v shows intra-dependency - test(new File(testDir, "Test.class"), - new String[] {"java.lang.Object", "p.Foo"}, - new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"}); + /* Temporary disable this test case. Test.class has a dependency + * on java.lang.String on certain windows machine (8008479). + // -v shows intra-dependency + test(new File(testDir, "Test.class"), + new String[] {"java.lang.Object", "p.Foo"}, + new String[] {"compact1", testDir.getName()}, + new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"}); + */ return errors; } - void test(File file, String[] expect) { - test(file, expect, new String[0]); + void test(File file, String[] expect, String[] profiles) { + test(file, expect, profiles, new String[0]); } - void test(File file, String[] expect, String[] options) { - String[] args; + void test(File file, String[] expect, String[] profiles, String[] options) { + List<String> args = new ArrayList<>(Arrays.asList(options)); if (file != null) { - args = Arrays.copyOf(options, options.length+1); - args[options.length] = file.getPath(); - } else { - args = options; + args.add(file.getPath()); } - String[] deps = jdeps(args); - checkEqual("dependencies", expect, deps); + List<String> argsWithDashP = new ArrayList<>(); + argsWithDashP.add("-P"); + argsWithDashP.addAll(args); + // test without -P + checkResult("dependencies", expect, jdeps(args.toArray(new String[0])).keySet()); + // test with -P + checkResult("profiles", expect, profiles, jdeps(argsWithDashP.toArray(new String[0]))); } - String[] jdeps(String... args) { + Map<String,String> jdeps(String... args) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); System.err.println("jdeps " + Arrays.toString(args)); @@ -112,12 +150,12 @@ // Pattern used to parse lines private static Pattern linePattern = Pattern.compile(".*\r?\n"); - private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +.*"); + private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)"); // Use the linePattern to break the given String into lines, applying // the pattern to each line to see if we have a match - private static String[] findDeps(String out) { - List<String> result = new ArrayList<>(); + private static Map<String,String> findDeps(String out) { + Map<String,String> result = new HashMap<>(); Matcher lm = linePattern.matcher(out); // Line matcher Matcher pm = null; // Pattern matcher int lines = 0; @@ -129,19 +167,41 @@ else pm.reset(cs); if (pm.find()) - result.add(pm.group(1)); + result.put(pm.group(1), pm.group(2).trim()); if (lm.end() == out.length()) break; } - return result.toArray(new String[0]); + return result; + } + + void checkResult(String label, String[] expect, Collection<String> found) { + List<String> list = Arrays.asList(expect); + if (!isEqual(list, found)) + error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); } - void checkEqual(String label, String[] expect, String[] found) { - Set<String> s1 = new HashSet<>(Arrays.asList(expect)); - Set<String> s2 = new HashSet<>(Arrays.asList(found)); + void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) { + if (expect.length != profiles.length) + error("Invalid expected names and profiles"); - if (!s1.equals(s2)) - error("Unexpected " + label + " found: '" + s2 + "', expected: '" + s1 + "'"); + // check the dependencies + checkResult(label, expect, result.keySet()); + // check profile information + checkResult(label, profiles, result.values()); + for (int i=0; i < expect.length; i++) { + String profile = result.get(expect[i]); + if (!profile.equals(profiles[i])) + error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'"); + } + } + + boolean isEqual(List<String> expected, Collection<String> found) { + if (expected.size() != found.size()) + return false; + + List<String> list = new ArrayList<>(found); + list.removeAll(expected); + return list.isEmpty(); } void error(String msg) {
--- a/test/tools/jdeps/p/Foo.java Mon Mar 25 16:55:14 2013 -0700 +++ b/test/tools/jdeps/p/Foo.java Mon Mar 25 18:08:47 2013 -0700 @@ -31,5 +31,7 @@ } public Foo() { + // compact3 + java.lang.management.ManagementFactory.getRuntimeMXBean(); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/jdeps/profiles.properties Mon Mar 25 18:08:47 2013 -0700 @@ -0,0 +1,263 @@ +# This properties file is used for testing a JDK development build. +# No need to keep this properties file up to date as long as it covers +# the APIs used by the jdeps regression test. +profile.1.name = compact1 +profile.1.packages = \ + java.io \ + java.lang \ + java.lang.annotation \ + java.lang.invoke \ + java.lang.ref \ + java.lang.reflect \ + java.math \ + java.net \ + java.nio \ + java.nio.channels \ + java.nio.channels.spi \ + java.nio.charset \ + java.nio.charset.spi \ + java.nio.file \ + java.nio.file.attribute \ + java.nio.file.spi \ + java.security \ + java.security.cert \ + java.security.interfaces \ + java.security.spec \ + java.text \ + java.text.spi \ + java.util \ + java.util.concurrent \ + java.util.concurrent.atomic \ + java.util.concurrent.locks \ + java.util.jar \ + java.util.logging \ + java.util.regex \ + java.util.spi \ + java.util.zip \ + javax.crypto \ + javax.crypto.interfaces \ + javax.crypto.spec \ + javax.security.auth \ + javax.security.auth.callback \ + javax.security.auth.login \ + javax.security.auth.spi \ + javax.security.auth.x500 \ + javax.net \ + javax.net.ssl \ + javax.security.cert \ + \ + com.sun.net.ssl \ + com.sun.nio.file \ + com.sun.nio.sctp \ + com.sun.security.auth \ + com.sun.security.auth.login + +profile.2.name = compact2 +profile.2.packages = \ + java.sql \ + javax.sql \ + javax.xml \ + javax.xml.datatype \ + javax.xml.namespace \ + javax.xml.parsers \ + javax.xml.stream \ + javax.xml.stream.events \ + javax.xml.stream.util \ + javax.xml.transform \ + javax.xml.transform.dom \ + javax.xml.transform.sax \ + javax.xml.transform.stax \ + javax.xml.transform.stream \ + javax.xml.validation \ + javax.xml.xpath \ + org.w3c.dom \ + org.w3c.dom.bootstrap \ + org.w3c.dom.events \ + org.w3c.dom.ls \ + org.xml.sax \ + org.xml.sax.ext \ + org.xml.sax.helpers \ + java.rmi \ + java.rmi.activation \ + java.rmi.dgc \ + java.rmi.registry \ + java.rmi.server \ + javax.rmi.ssl \ + javax.transaction \ + javax.transaction.xa \ + \ + com.sun.net.httpserver \ + com.sun.net.httpserver.spi + +profile.3.name = compact3 +profile.3.packages = \ + java.lang.instrument \ + java.lang.management \ + java.security.acl \ + java.util.prefs \ + javax.management \ + javax.management.loading \ + javax.management.modelmbean \ + javax.management.monitor \ + javax.management.openmbean \ + javax.management.relation \ + javax.management.remote \ + javax.management.remote.rmi \ + javax.management.timer \ + javax.naming \ + javax.naming.directory \ + javax.naming.event \ + javax.naming.ldap \ + javax.naming.spi \ + javax.sql.rowset \ + javax.sql.rowset.serial \ + javax.sql.rowset.spi \ + javax.security.auth.kerberos \ + javax.security.sasl \ + javax.script \ + javax.smartcardio \ + javax.xml.crypto \ + javax.xml.crypto.dom \ + javax.xml.crypto.dsig \ + javax.xml.crypto.dsig.dom \ + javax.xml.crypto.dsig.keyinfo \ + javax.xml.crypto.dsig.spec \ + javax.annotation.processing \ + javax.lang.model \ + javax.lang.model.element \ + javax.lang.model.type \ + javax.lang.model.util \ + javax.tools \ + javax.tools.annotation \ + org.ietf.jgss \ + \ + com.sun.management \ + com.sun.security.auth.callback \ + com.sun.security.auth.module \ + com.sun.security.jgss + +profile.4.name = Full JRE +profile.4.packages = \ + java.applet \ + java.awt \ + java.awt.color \ + java.awt.datatransfer \ + java.awt.dnd \ + java.awt.dnd.peer \ + java.awt.event \ + java.awt.font \ + java.awt.geom \ + java.awt.im \ + java.awt.im.spi \ + java.awt.image \ + java.awt.image.renderable \ + java.awt.peer \ + java.awt.print \ + java.beans \ + java.beans.beancontext \ + javax.accessibility \ + javax.imageio \ + javax.imageio.event \ + javax.imageio.metadata \ + javax.imageio.plugins.bmp \ + javax.imageio.plugins.jpeg \ + javax.imageio.spi \ + javax.imageio.stream \ + javax.print \ + javax.print.attribute \ + javax.print.attribute.standard \ + javax.print.event \ + javax.sound.midi \ + javax.sound.midi.spi \ + javax.sound.sampled \ + javax.sound.sampled.spi \ + javax.swing \ + javax.swing.border \ + javax.swing.colorchooser \ + javax.swing.event \ + javax.swing.filechooser \ + javax.swing.plaf \ + javax.swing.plaf.basic \ + javax.swing.plaf.metal \ + javax.swing.plaf.multi \ + javax.swing.plaf.nimbus \ + javax.swing.plaf.synth \ + javax.swing.table \ + javax.swing.text \ + javax.swing.text.html \ + javax.swing.text.html.parser \ + javax.swing.text.rtf \ + javax.swing.tree \ + javax.swing.undo \ + javax.activation \ + javax.jws \ + javax.jws.soap \ + javax.rmi \ + javax.rmi.CORBA \ + javax.xml.bind \ + javax.xml.bind.annotation \ + javax.xml.bind.annotation.adapters \ + javax.xml.bind.attachment \ + javax.xml.bind.helpers \ + javax.xml.bind.util \ + javax.xml.soap \ + javax.xml.ws \ + javax.xml.ws.handler \ + javax.xml.ws.handler.soap \ + javax.xml.ws.http \ + javax.xml.ws.soap \ + javax.xml.ws.spi \ + javax.xml.ws.spi.http \ + javax.xml.ws.wsaddressing \ + javax.annotation \ + org.omg.CORBA \ + org.omg.CORBA.DynAnyPackage \ + org.omg.CORBA.ORBPackage \ + org.omg.CORBA.TypeCodePackage \ + org.omg.CORBA.portable \ + org.omg.CORBA_2_3 \ + org.omg.CORBA_2_3.portable \ + org.omg.CosNaming \ + org.omg.CosNaming.NamingContextExtPackage \ + org.omg.CosNaming.NamingContextPackage \ + org.omg.Dynamic \ + org.omg.DynamicAny \ + org.omg.DynamicAny.DynAnyFactoryPackage \ + org.omg.DynamicAny.DynAnyPackage \ + org.omg.IOP \ + org.omg.IOP.CodecFactoryPackage \ + org.omg.IOP.CodecPackage \ + org.omg.Messaging \ + org.omg.PortableInterceptor \ + org.omg.PortableInterceptor.ORBInitInfoPackage \ + org.omg.PortableServer \ + org.omg.PortableServer.CurrentPackage \ + org.omg.PortableServer.POAManagerPackage \ + org.omg.PortableServer.POAPackage \ + org.omg.PortableServer.ServantLocatorPackage \ + org.omg.PortableServer.portable \ + org.omg.SendingContext \ + org.omg.stub.java.rmi \ + org.omg.stub.javax.management.remote.rmi + +# Remaining JDK supported API +profile.5.name = JDK tools +profile.5.packages = \ + com.sun.jdi \ + com.sun.jdi.connect \ + com.sun.jdi.connect.spi \ + com.sun.jdi.event \ + com.sun.jdi.request \ + com.sun.javadoc \ + com.sun.tools.doclets \ + com.sun.tools.doctree \ + com.sun.source.tree \ + com.sun.source.util \ + com.sun.tools.attach \ + com.sun.tools.attach.spi \ + com.sun.tools.jconsole \ + com.sun.tools.javac \ + com.sun.tools.javah \ + com.sun.tools.javap \ + com.sun.tools.javadoc \ + com.sun.servicetag