# HG changeset patch # User lana # Date 1356748749 28800 # Node ID 467e4d9281bcf119eaec42af1423c96bd401871c # Parent 7d5032c2d747843af58b55cce4dcb90be3d46d10# Parent 690c41cdab55c3f1b6eb3f6b4e38de1d1aa0272d Merge diff -r 7d5032c2d747 -r 467e4d9281bc make/build.properties --- a/make/build.properties Thu Dec 27 12:15:17 2012 -0800 +++ b/make/build.properties Fri Dec 28 18:39:09 2012 -0800 @@ -68,7 +68,7 @@ # set the following to -version to verify the versions of javac being used javac.version.opt = # in time, there should be no exceptions to -Xlint:all -javac.lint.opts = -Xlint:all,-deprecation -Werror +javac.lint.opts = -Xlint:all -Werror # options for the task for javac #javadoc.jls3.url=http://java.sun.com/docs/books/jls/ @@ -117,7 +117,8 @@ javax/lang/model/ \ javax/tools/ \ com/sun/source/ \ - com/sun/tools/javac/ + com/sun/tools/javac/ \ + com/sun/tools/doclint/ javac.tests = \ tools/javac diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/javadoc/ClassDoc.java --- a/src/share/classes/com/sun/javadoc/ClassDoc.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/javadoc/ClassDoc.java Fri Dec 28 18:39:09 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -66,6 +66,12 @@ boolean isExternalizable(); /** + * Return true if this class can be used as a target type of a lambda expression + * or method reference. + */ + boolean isFunctionalInterface(); + + /** * Return the serialization methods for this class or * interface. * diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/javadoc/MethodDoc.java --- a/src/share/classes/com/sun/javadoc/MethodDoc.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/javadoc/MethodDoc.java Fri Dec 28 18:39:09 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -39,6 +39,11 @@ boolean isAbstract(); /** + * Return true if this method is default + */ + boolean isDefault(); + + /** * Get return type. * * @return the return type of this method, null if it diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/source/util/DocTrees.java --- a/src/share/classes/com/sun/source/util/DocTrees.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/source/util/DocTrees.java Fri Dec 28 18:39:09 2012 -0800 @@ -45,9 +45,7 @@ * @throws IllegalArgumentException if the task does not support the Trees API. */ public static DocTrees instance(CompilationTask task) { - if (!task.getClass().getName().equals("com.sun.tools.javac.api.JavacTaskImpl")) - throw new IllegalArgumentException(); - return (DocTrees) getJavacTrees(CompilationTask.class, task); + return (DocTrees) Trees.instance(task); } /** diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/source/util/JavacTask.java --- a/src/share/classes/com/sun/source/util/JavacTask.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/source/util/JavacTask.java Fri Dec 28 18:39:09 2012 -0800 @@ -139,6 +139,7 @@ * @see com.sun.source.util.Trees#getTypeMirror */ public abstract TypeMirror getTypeMirror(Iterable path); + /** * Get a utility object for dealing with program elements. */ diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/source/util/Plugin.java --- a/src/share/classes/com/sun/source/util/Plugin.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/source/util/Plugin.java Fri Dec 28 18:39:09 2012 -0800 @@ -56,9 +56,9 @@ String getName(); /** - * Invoke the plug-in for a given compilation task. + * Initialize the plug-in for a given compilation task. * @param task The compilation task that has just been started * @param args Arguments, if any, for the plug-in */ - void call(JavacTask task, String... args); + void init(JavacTask task, String... args); } diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/source/util/TreePath.java --- a/src/share/classes/com/sun/source/util/TreePath.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/source/util/TreePath.java Fri Dec 28 18:39:09 2012 -0800 @@ -60,14 +60,20 @@ this.path = path; } } + class PathFinder extends TreePathScanner { public TreePath scan(Tree tree, Tree target) { - if (tree == target) + if (tree == target) { throw new Result(new TreePath(getCurrentPath(), target)); + } return super.scan(tree, target); } } + if (path.getLeaf() == target) { + return path; + } + try { new PathFinder().scan(path, target); } catch (Result result) { diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java --- a/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java Fri Dec 28 18:39:09 2012 -0800 @@ -239,7 +239,14 @@ if ((member.isField() || member.isMethod()) && writer instanceof ClassWriterImpl && ((ClassWriterImpl) writer).getClassDoc().isInterface()) { - mod = Util.replaceText(mod, "public", "").trim(); + // This check for isDefault() and the default modifier needs to be + // added for it to appear on the method details section. Once the + // default modifier is added to the Modifier list on DocEnv and once + // it is updated to use the javax.lang.model.element.Modifier, we + // will need to remove this. + mod = (member.isMethod() && ((MethodDoc)member).isDefault()) ? + Util.replaceText(mod, "public", "default").trim() : + Util.replaceText(mod, "public", "").trim(); } if(mod.length() > 0) { htmltree.addContent(mod); @@ -313,8 +320,18 @@ code.addContent(configuration.getText("doclet.Package_private")); code.addContent(" "); } - if (member.isMethod() && ((MethodDoc)member).isAbstract()) { - code.addContent("abstract "); + if (member.isMethod()) { + if (((MethodDoc)member).isAbstract()) { + code.addContent("abstract "); + } + // This check for isDefault() and the default modifier needs to be + // added for it to appear on the "Modifier and Type" column in the + // method summary section. Once the default modifier is added + // to the Modifier list on DocEnv and once it is updated to use the + // javax.lang.model.element.Modifier, we will need to remove this. + else if (((MethodDoc)member).isDefault()) { + code.addContent("default "); + } } if (member.isStatic()) { code.addContent("static "); @@ -547,6 +564,9 @@ methodType = (classdoc.isInterface() || ((MethodDoc)member).isAbstract()) ? methodType | MethodTypes.ABSTRACT.value() : methodType | MethodTypes.CONCRETE.value(); + if (((MethodDoc)member).isDefault()) { + methodType = methodType | MethodTypes.DEFAULT.value(); + } if (Util.isDeprecated(member) || Util.isDeprecated(classdoc)) { methodType = methodType | MethodTypes.DEPRECATED.value(); } diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java --- a/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Fri Dec 28 18:39:09 2012 -0800 @@ -516,6 +516,20 @@ /** * {@inheritDoc} */ + public void addFunctionalInterfaceInfo (Content classInfoTree) { + if (classDoc.isFunctionalInterface()) { + Content dt = HtmlTree.DT(getResource("doclet.Functional_Interface")); + Content dl = HtmlTree.DL(dt); + Content dd = new HtmlTree(HtmlTag.DD); + dd.addContent(getResource("doclet.Functional_Interface_Message")); + dl.addContent(dd); + classInfoTree.addContent(dl); + } + } + + /** + * {@inheritDoc} + */ public void addClassDeprecationInfo(Content classInfoTree) { Content hr = new HtmlTree(HtmlTag.HR); classInfoTree.addContent(hr); diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties --- a/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Fri Dec 28 18:39:09 2012 -0800 @@ -90,6 +90,8 @@ doclet.Subclasses=Direct Known Subclasses: doclet.Subinterfaces=All Known Subinterfaces: doclet.Implementing_Classes=All Known Implementing Classes: +doclet.Functional_Interface=Functional Interface: +doclet.Functional_Interface_Message=This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. doclet.also=also doclet.Frames=Frames doclet.No_Frames=No Frames diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/internal/toolkit/ClassWriter.java --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/ClassWriter.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/ClassWriter.java Fri Dec 28 18:39:09 2012 -0800 @@ -117,6 +117,13 @@ public void addInterfaceUsageInfo(Content classInfoTree); /** + * If this is an functional interface, display appropriate message. + * + * @param classInfoTree content tree to which the documentation will be added + */ + public void addFunctionalInterfaceInfo(Content classInfoTree); + + /** * If this is an inner class or interface, add the enclosing class or * interface. * diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java Fri Dec 28 18:39:09 2012 -0800 @@ -236,6 +236,16 @@ } /** + * If this is an functional interface, display appropriate message. + * + * @param node the XML element that specifies which components to document + * @param classInfoTree the content tree to which the documentation will be added + */ + public void buildFunctionalInterfaceInfo(XMLNode node, Content classInfoTree) { + writer.addFunctionalInterfaceInfo(classInfoTree); + } + + /** * If this class is deprecated, build the appropriate information. * * @param node the XML element that specifies which components to document diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml Fri Dec 28 18:39:09 2012 -0800 @@ -85,6 +85,7 @@ + diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MethodTypes.java --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MethodTypes.java Thu Dec 27 12:15:17 2012 -0800 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MethodTypes.java Fri Dec 28 18:39:09 2012 -0800 @@ -36,7 +36,8 @@ INSTANCE(0x2, "Instance Methods", "t2", false), ABSTRACT(0x4, "Abstract Methods", "t3", false), CONCRETE(0x8, "Concrete Methods", "t4", false), - DEPRECATED(0x10, "Deprecated Methods", "t5", false); + DEFAULT(0x10, "Default Methods", "t5", false), + DEPRECATED(0x20, "Deprecated Methods", "t6", false); private final int value; private final String text; diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/Checker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/Checker.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclint; + +import java.util.regex.Matcher; +import com.sun.source.doctree.LinkTree; +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.util.Deque; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic.Kind; + +import com.sun.source.doctree.AttributeTree; +import com.sun.source.doctree.AuthorTree; +import com.sun.source.doctree.DocCommentTree; +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.ParamTree; +import com.sun.source.doctree.ReferenceTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.SerialDataTree; +import com.sun.source.doctree.SerialFieldTree; +import com.sun.source.doctree.SinceTree; +import com.sun.source.doctree.StartElementTree; +import com.sun.source.doctree.TextTree; +import com.sun.source.doctree.ThrowsTree; +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 static com.sun.tools.doclint.Messages.Group.*; + + +/** + * Validate a doc comment. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class Checker extends DocTreeScanner { + final Env env; + + Set foundParams = new HashSet(); + Set foundThrows = new HashSet(); + Set foundAnchors = new HashSet(); + boolean foundInheritDoc = false; + boolean foundReturn = false; + + enum Flag { + TABLE_HAS_CAPTION, + HAS_ELEMENT, + HAS_TEXT + } + + static class TagStackItem { + final DocTree tree; // typically, but not always, StartElementTree + final HtmlTag tag; + final Set attrs; + final Set flags; + TagStackItem(DocTree tree, HtmlTag tag) { + this.tree = tree; + this.tag = tag; + attrs = EnumSet.noneOf(HtmlTag.Attr.class); + flags = EnumSet.noneOf(Flag.class); + } + @Override + public String toString() { + return String.valueOf(tag); + } + } + + private Deque tagStack; // TODO: maybe want to record starting tree as well + private HtmlTag currHeaderTag; + + // + + Checker(Env env) { + env.getClass(); + this.env = env; + tagStack = new LinkedList(); + } + + public Void scan(DocCommentTree tree, TreePath p) { + env.setCurrent(p, tree); + + boolean isOverridingMethod = !env.currOverriddenMethods.isEmpty(); + + if (tree == null) { + if (!isSynthetic() && !isOverridingMethod) + reportMissing("dc.missing.comment"); + return null; + } + + tagStack.clear(); + currHeaderTag = null; + + foundParams.clear(); + foundThrows.clear(); + foundInheritDoc = false; + foundReturn = false; + + scan(tree, (Void) null); + + if (!isOverridingMethod) { + switch (env.currElement.getKind()) { + case METHOD: + case CONSTRUCTOR: { + ExecutableElement ee = (ExecutableElement) env.currElement; + checkParamsDocumented(ee.getTypeParameters()); + checkParamsDocumented(ee.getParameters()); + switch (ee.getReturnType().getKind()) { + case VOID: + case NONE: + break; + default: + if (!foundReturn + && !foundInheritDoc + && !env.types.isSameType(ee.getReturnType(), env.java_lang_Void)) { + reportMissing("dc.missing.return"); + } + } + checkThrowsDocumented(ee.getThrownTypes()); + } + } + } + + return null; + } + + private void reportMissing(String code, Object... args) { + env.messages.report(MISSING, Kind.WARNING, env.currPath.getLeaf(), code, args); + } + + @Override + public Void visitDocComment(DocCommentTree tree, Void ignore) { + super.visitDocComment(tree, ignore); + for (TagStackItem tsi: tagStack) { + if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT + && tsi.tag.endKind == HtmlTag.EndKind.REQUIRED) { + StartElementTree t = (StartElementTree) tsi.tree; + env.messages.error(HTML, t, "dc.tag.not.closed", t.getName()); + } + } + return null; + } + // + + // + + @Override + public Void visitText(TextTree tree, Void ignore) { + if (!tree.getBody().trim().isEmpty()) { + markEnclosingTag(Flag.HAS_TEXT); + } + return null; + } + + @Override + public Void visitEntity(EntityTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_TEXT); + String name = tree.getName().toString(); + if (name.startsWith("#")) { + int v = name.toLowerCase().startsWith("#x") + ? Integer.parseInt(name.substring(2), 16) + : Integer.parseInt(name.substring(1), 10); + if (!Entity.isValid(v)) { + env.messages.error(HTML, tree, "dc.entity.invalid", name); + } + } else if (!Entity.isValid(name)) { + env.messages.error(HTML, tree, "dc.entity.invalid", name); + } + return null; + } + + // + + // + + @Override + public Void visitStartElement(StartElementTree tree, Void ignore) { + markEnclosingTag(Flag.HAS_ELEMENT); + final Name treeName = tree.getName(); + final HtmlTag t = HtmlTag.get(treeName); + if (t == null) { + env.messages.error(HTML, tree, "dc.tag.unknown", treeName); + } else { + // tag specific checks + switch (t) { + // check for out of sequence headers, such as

...

...

+ case H1: case H2: case H3: case H4: case H5: case H6: + checkHeader(tree, t); + break; + //

inside

+                case P:
+                    TagStackItem top = tagStack.peek();
+                    if (top != null && top.tag == HtmlTag.PRE)
+                        env.messages.warning(HTML, tree, "dc.tag.p.in.pre");
+                    break;
+            }
+
+            // check that only block tags and inline tags are used,
+            // and that blocks tags are not used within inline tags
+            switch (t.blockType) {
+                case INLINE:
+                    break;
+                case BLOCK:
+                    TagStackItem top = tagStack.peek();
+                    if (top != null && top.tag != null && top.tag.blockType == HtmlTag.BlockType.INLINE) {
+                        switch (top.tree.getKind()) {
+                            case START_ELEMENT: {
+                                Name name = ((StartElementTree) top.tree).getName();
+                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
+                                        treeName, name);
+                                break;
+                            }
+                            case LINK:
+                            case LINK_PLAIN: {
+                                String name = top.tree.getKind().tagName;
+                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
+                                        treeName, name);
+                                break;
+                            }
+                            default:
+                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.other",
+                                        treeName);
+                        }
+                    }
+                    break;
+                case OTHER:
+                    env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+                    break;
+                default:
+                    throw new AssertionError();
+            }
+
+            if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
+                for (TagStackItem i: tagStack) {
+                    if (t == i.tag) {
+                        env.messages.warning(HTML, tree, "dc.tag.nested.not.allowed", treeName);
+                        break;
+                    }
+                }
+            }
+        }
+
+        // check for self closing tags, such as 
+        if (tree.isSelfClosing()) {
+            env.messages.error(HTML, tree, "dc.tag.self.closing", treeName);
+        }
+
+        try {
+            TagStackItem parent = tagStack.peek();
+            TagStackItem top = new TagStackItem(tree, t);
+            tagStack.push(top);
+
+            super.visitStartElement(tree, ignore);
+
+            // handle attributes that may or may not have been found in start element
+            if (t != null) {
+                switch (t) {
+                    case CAPTION:
+                        if (parent != null && parent.tag == HtmlTag.TABLE)
+                            parent.flags.add(Flag.TABLE_HAS_CAPTION);
+                        break;
+
+                    case IMG:
+                        if (!top.attrs.contains(HtmlTag.Attr.ALT))
+                            env.messages.error(ACCESSIBILITY, tree, "dc.no.alt.attr.for.image");
+                        break;
+                }
+            }
+
+            return null;
+        } finally {
+
+            if (t == null || t.endKind == HtmlTag.EndKind.NONE)
+                tagStack.pop();
+        }
+    }
+
+    private void checkHeader(StartElementTree tree, HtmlTag tag) {
+        // verify the new tag
+        if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) {
+            if (currHeaderTag == null) {
+                env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.1", tag);
+            } else {
+                env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.2",
+                    tag, currHeaderTag);
+            }
+        }
+
+        currHeaderTag = tag;
+    }
+
+    private int getHeaderLevel(HtmlTag tag) {
+        if (tag == null)
+            return 0;
+        switch (tag) {
+            case H1: return 1;
+            case H2: return 2;
+            case H3: return 3;
+            case H4: return 4;
+            case H5: return 5;
+            case H6: return 6;
+            default: throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    public Void visitEndElement(EndElementTree tree, Void ignore) {
+        final Name treeName = tree.getName();
+        final HtmlTag t = HtmlTag.get(treeName);
+        if (t == null) {
+            env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
+        } else if (t.endKind == HtmlTag.EndKind.NONE) {
+            env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName);
+        } else if (tagStack.isEmpty()) {
+            env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+        } else {
+            while (!tagStack.isEmpty()) {
+                TagStackItem top = tagStack.peek();
+                if (t == top.tag) {
+                    switch (t) {
+                        case TABLE:
+                            if (!top.attrs.contains(HtmlTag.Attr.SUMMARY)
+                                    && !top.flags.contains(Flag.TABLE_HAS_CAPTION)) {
+                                env.messages.error(ACCESSIBILITY, tree,
+                                        "dc.no.summary.or.caption.for.table");
+                            }
+                    }
+                    if (t.flags.contains(HtmlTag.Flag.EXPECT_CONTENT)
+                            && !top.flags.contains(Flag.HAS_TEXT)
+                            && !top.flags.contains(Flag.HAS_ELEMENT)) {
+                        env.messages.warning(HTML, tree, "dc.tag.empty", treeName);
+                    }
+                    if (t.flags.contains(HtmlTag.Flag.NO_TEXT)
+                            && top.flags.contains(Flag.HAS_TEXT)) {
+                        env.messages.error(HTML, tree, "dc.text.not.allowed", treeName);
+                    }
+                    tagStack.pop();
+                    break;
+                } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
+                    tagStack.pop();
+                } else {
+                    boolean found = false;
+                    for (TagStackItem si: tagStack) {
+                        if (si.tag == t) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (found && top.tree.getKind() == DocTree.Kind.START_ELEMENT) {
+                        env.messages.error(HTML, top.tree, "dc.tag.start.unmatched",
+                                ((StartElementTree) top.tree).getName());
+                        tagStack.pop();
+                    } else {
+                        env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+                        break;
+                    }
+                }
+            }
+        }
+
+        return super.visitEndElement(tree, ignore);
+    }
+    // 
+
+    // 
+
+    @Override @SuppressWarnings("fallthrough")
+    public Void visitAttribute(AttributeTree tree, Void ignore) {
+        HtmlTag currTag = tagStack.peek().tag;
+        if (currTag != null) {
+            Name name = tree.getName();
+            HtmlTag.Attr attr = currTag.getAttr(name);
+            if (attr != null) {
+                boolean first = tagStack.peek().attrs.add(attr);
+                if (!first)
+                    env.messages.error(HTML, tree, "dc.attr.repeated", name);
+            }
+            AttrKind k = currTag.getAttrKind(name);
+            switch (k) {
+                case OK:
+                    break;
+
+                case INVALID:
+                    env.messages.error(HTML, tree, "dc.attr.unknown", name);
+                    break;
+
+                case OBSOLETE:
+                    env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name);
+                    break;
+
+                case USE_CSS:
+                    env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name);
+                    break;
+            }
+
+            if (attr != null) {
+                switch (attr) {
+                    case NAME:
+                        if (currTag != HtmlTag.A) {
+                            break;
+                        }
+                    // fallthrough
+                    case ID:
+                        String value = getAttrValue(tree);
+                        if (!validName.matcher(value).matches()) {
+                            env.messages.error(HTML, tree, "dc.invalid.anchor", value);
+                        }
+                        if (!foundAnchors.add(value)) {
+                            env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+                        }
+                        break;
+
+                    case HREF:
+                        if (currTag == HtmlTag.A) {
+                            String v = getAttrValue(tree);
+                            if (v == null || v.isEmpty()) {
+                                env.messages.error(HTML, tree, "dc.attr.lacks.value");
+                            } else {
+                                Matcher m = docRoot.matcher(v);
+                                if (m.matches()) {
+                                    String rest = m.group(2);
+                                    if (!rest.isEmpty())
+                                        checkURI(tree, rest);
+                                } else {
+                                    checkURI(tree, v);
+                                }
+                            }
+                        }
+                        break;
+                }
+            }
+        }
+
+        // TODO: basic check on value
+
+        return super.visitAttribute(tree, ignore);
+    }
+
+    // http://www.w3.org/TR/html401/types.html#type-name
+    private static final Pattern validName = Pattern.compile("[A-Za-z][A-Za-z0-9-_:.]*");
+
+    // pattern to remove leading {@docRoot}/?
+    private static final Pattern docRoot = Pattern.compile("(?i)(\\{@docRoot *\\}/?)?(.*)");
+
+    private String getAttrValue(AttributeTree tree) {
+        if (tree.getValue() == null)
+            return null;
+
+        StringWriter sw = new StringWriter();
+        try {
+            new DocPretty(sw).print(tree.getValue());
+        } catch (IOException e) {
+            // cannot happen
+        }
+        // ignore potential use of entities for now
+        return sw.toString();
+    }
+
+    private void checkURI(AttributeTree tree, String uri) {
+        try {
+            URI u = new URI(uri);
+        } catch (URISyntaxException e) {
+            env.messages.error(HTML, tree, "dc.invalid.uri", uri);
+        }
+    }
+    // 
+
+    // 
+
+    @Override
+    public Void visitAuthor(AuthorTree tree, Void ignore) {
+        warnIfEmpty(tree, tree.getName());
+        return super.visitAuthor(tree, ignore);
+    }
+
+    @Override
+    public Void visitInheritDoc(InheritDocTree tree, Void ignore) {
+        // TODO: verify on overridden method
+        foundInheritDoc = true;
+        return super.visitInheritDoc(tree, ignore);
+    }
+
+    @Override
+    public Void visitLink(LinkTree tree, Void ignore) {
+        // simulate inline context on tag stack
+        HtmlTag t = (tree.getKind() == DocTree.Kind.LINK)
+                ? HtmlTag.CODE : HtmlTag.SPAN;
+        tagStack.push(new TagStackItem(tree, t));
+        try {
+            return super.visitLink(tree, ignore);
+        } finally {
+            tagStack.pop();
+        }
+    }
+
+    @Override
+    public Void visitParam(ParamTree tree, Void ignore) {
+        boolean typaram = tree.isTypeParameter();
+        IdentifierTree nameTree = tree.getName();
+        Element e = env.currElement;
+        switch (e.getKind()) {
+            case METHOD: case CONSTRUCTOR: {
+                ExecutableElement ee = (ExecutableElement) e;
+                checkParamDeclared(nameTree, typaram ? ee.getTypeParameters() : ee.getParameters());
+                break;
+            }
+
+            case CLASS: case INTERFACE: {
+                TypeElement te = (TypeElement) e;
+                if (typaram) {
+                    checkParamDeclared(nameTree, te.getTypeParameters());
+                } else {
+                    env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                }
+                break;
+            }
+
+            default:
+                env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                break;
+        }
+        warnIfEmpty(tree, tree.getDescription());
+        return super.visitParam(tree, ignore);
+    }
+    // where
+    private void checkParamDeclared(IdentifierTree nameTree, List list) {
+        Name name = nameTree.getName();
+        boolean found = false;
+        for (Element e: list) {
+            if (name.equals(e.getSimpleName())) {
+                foundParams.add(e);
+                found = true;
+            }
+        }
+        if (!found)
+            env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
+    }
+
+    private void checkParamsDocumented(List list) {
+        if (foundInheritDoc)
+            return;
+
+        for (Element e: list) {
+            if (!foundParams.contains(e)) {
+                CharSequence paramName = (e.getKind() == ElementKind.TYPE_PARAMETER)
+                        ? "<" + e.getSimpleName() + ">"
+                        : e.getSimpleName();
+                reportMissing("dc.missing.param", paramName);
+            }
+        }
+    }
+
+    @Override
+    public Void visitReference(ReferenceTree tree, Void ignore) {
+        Element e = env.trees.getElement(env.currPath, tree);
+        if (e == null)
+            env.messages.error(REFERENCE, tree, "dc.ref.not.found");
+        return super.visitReference(tree, ignore);
+    }
+
+    @Override
+    public Void visitReturn(ReturnTree tree, Void ignore) {
+        Element e = env.trees.getElement(env.currPath);
+        if (e.getKind() != ElementKind.METHOD
+                || ((ExecutableElement) e).getReturnType().getKind() == TypeKind.VOID)
+            env.messages.error(REFERENCE, tree, "dc.invalid.return");
+        foundReturn = true;
+        warnIfEmpty(tree, tree.getDescription());
+        return super.visitReturn(tree, ignore);
+    }
+
+    @Override
+    public Void visitSerialData(SerialDataTree tree, Void ignore) {
+        warnIfEmpty(tree, tree.getDescription());
+        return super.visitSerialData(tree, ignore);
+    }
+
+    @Override
+    public Void visitSerialField(SerialFieldTree tree, Void ignore) {
+        warnIfEmpty(tree, tree.getDescription());
+        return super.visitSerialField(tree, ignore);
+    }
+
+    @Override
+    public Void visitSince(SinceTree tree, Void ignore) {
+        warnIfEmpty(tree, tree.getBody());
+        return super.visitSince(tree, ignore);
+    }
+
+    @Override
+    public Void visitThrows(ThrowsTree tree, Void ignore) {
+        ReferenceTree exName = tree.getExceptionName();
+        Element ex = env.trees.getElement(env.currPath, exName);
+        if (ex == null) {
+            env.messages.error(REFERENCE, tree, "dc.ref.not.found");
+        } else if (ex.asType().getKind() == TypeKind.DECLARED
+                && env.types.isAssignable(ex.asType(), env.java_lang_Throwable)) {
+            switch (env.currElement.getKind()) {
+                case CONSTRUCTOR:
+                case METHOD:
+                    if (isCheckedException(ex.asType())) {
+                        ExecutableElement ee = (ExecutableElement) env.currElement;
+                        checkThrowsDeclared(exName, ex.asType(), ee.getThrownTypes());
+                    }
+                    break;
+                default:
+                    env.messages.error(REFERENCE, tree, "dc.invalid.throws");
+            }
+        } else {
+            env.messages.error(REFERENCE, tree, "dc.invalid.throws");
+        }
+        warnIfEmpty(tree, tree.getDescription());
+        return scan(tree.getDescription(), ignore);
+    }
+
+    private void checkThrowsDeclared(ReferenceTree tree, TypeMirror t, List list) {
+        boolean found = false;
+        for (TypeMirror tl : list) {
+            if (env.types.isAssignable(t, tl)) {
+                foundThrows.add(tl);
+                found = true;
+            }
+        }
+        if (!found)
+            env.messages.error(REFERENCE, tree, "dc.exception.not.thrown", t);
+    }
+
+    private void checkThrowsDocumented(List list) {
+        if (foundInheritDoc)
+            return;
+
+        for (TypeMirror tl: list) {
+            if (isCheckedException(tl) && !foundThrows.contains(tl))
+                reportMissing("dc.missing.throws", tl);
+        }
+    }
+
+    @Override
+    public Void visitVersion(VersionTree tree, Void ignore) {
+        warnIfEmpty(tree, tree.getBody());
+        return super.visitVersion(tree, ignore);
+    }
+
+    @Override
+    public Void visitErroneous(ErroneousTree tree, Void ignore) {
+        env.messages.error(SYNTAX, tree, null, tree.getDiagnostic().getMessage(null));
+        return null;
+    }
+    // 
+
+    // 
+
+    private boolean isCheckedException(TypeMirror t) {
+        return !(env.types.isAssignable(t, env.java_lang_Error)
+                || env.types.isAssignable(t, env.java_lang_RuntimeException));
+    }
+
+    private boolean isSynthetic() {
+        switch (env.currElement.getKind()) {
+            case CONSTRUCTOR:
+                // A synthetic default constructor has the same pos as the
+                // enclosing class
+                TreePath p = env.currPath;
+                return env.getPos(p) == env.getPos(p.getParentPath());
+        }
+        return false;
+    }
+
+    void markEnclosingTag(Flag flag) {
+        TagStackItem top = tagStack.peek();
+        if (top != null)
+            top.flags.add(flag);
+    }
+
+    String toString(TreePath p) {
+        StringBuilder sb = new StringBuilder("TreePath[");
+        toString(p, sb);
+        sb.append("]");
+        return sb.toString();
+    }
+
+    void toString(TreePath p, StringBuilder sb) {
+        TreePath parent = p.getParentPath();
+        if (parent != null) {
+            toString(parent, sb);
+            sb.append(",");
+        }
+       sb.append(p.getLeaf().getKind()).append(":").append(env.getPos(p)).append(":S").append(env.getStartPos(p));
+    }
+
+    void warnIfEmpty(DocTree tree, List list) {
+        for (DocTree d: list) {
+            switch (d.getKind()) {
+                case TEXT:
+                    if (!((TextTree) d).getBody().trim().isEmpty())
+                        return;
+                    break;
+                default:
+                    return;
+            }
+        }
+        env.messages.warning(SYNTAX, tree, "dc.empty", tree.getKind().tagName);
+    }
+    // 
+
+}
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/DocLint.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/doclint/DocLint.java	Fri Dec 28 18:39:09 2012 -0800
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclint;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.lang.model.element.Name;
+import javax.tools.StandardLocation;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.util.Context;
+
+/**
+ * Multi-function entry point for the doc check utility.
+ *
+ * This class can be invoked in the following ways:
+ * 
    + *
  • From the command line + *
  • From javac, as a plugin + *
  • Directly, via a simple API + *
+ * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class DocLint implements Plugin { + + public static final String XMSGS_OPTION = "-Xmsgs"; + public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:"; + private static final String STATS = "-stats"; + + // + public static void main(String... args) { + try { + new DocLint().run(args); + } catch (BadArgs e) { + System.err.println(e.getMessage()); + System.exit(1); + } catch (IOException e) { + System.err.println(e); + System.exit(2); + } + } + + // + + // + + public static class BadArgs extends Exception { + private static final long serialVersionUID = 0; + BadArgs(String code, Object... args) { + this.code = code; + this.args = args; + } + + final String code; + final Object[] args; + } + + /** + * Simple API entry point. + */ + public void run(String... args) throws BadArgs, IOException { + PrintWriter out = new PrintWriter(System.out); + try { + run(out, args); + } finally { + out.flush(); + } + } + + public void run(PrintWriter out, String... args) throws BadArgs, IOException { + env = new Env(); + processArgs(args); + + if (needHelp) + showHelp(out); + + if (javacFiles.isEmpty()) { + if (!needHelp) + System.out.println("no files given"); + } + + JavacTool tool = JavacTool.create(); + + JavacFileManager fm = new JavacFileManager(new Context(), false, null); + fm.setSymbolFileEnabled(false); + fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, javacBootClassPath); + fm.setLocation(StandardLocation.CLASS_PATH, javacClassPath); + fm.setLocation(StandardLocation.SOURCE_PATH, javacSourcePath); + + JavacTask task = tool.getTask(out, fm, null, javacOpts, null, + fm.getJavaFileObjectsFromFiles(javacFiles)); + Iterable units = task.parse(); + ((JavacTaskImpl) task).enter(); + + env.init(task); + checker = new Checker(env); + + DeclScanner ds = new DeclScanner() { + @Override + void visitDecl(Tree tree, Name name) { + TreePath p = getCurrentPath(); + DocCommentTree dc = env.trees.getDocCommentTree(p); + + checker.scan(dc, p); + } + }; + + ds.scan(units, null); + + reportStats(out); + + Context ctx = ((JavacTaskImpl) task).getContext(); + JavaCompiler c = JavaCompiler.instance(ctx); + c.printCount("error", c.errorCount()); + c.printCount("warn", c.warningCount()); + } + + void processArgs(String... args) throws BadArgs { + javacOpts = new ArrayList(); + javacFiles = new ArrayList(); + + if (args.length == 0) + needHelp = true; + + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (arg.matches("-Xmax(errs|warns)") && i + 1 < args.length) { + if (args[++i].matches("[0-9]+")) { + javacOpts.add(arg); + javacOpts.add(args[i]); + } else { + throw new BadArgs("dc.bad.value.for.option", arg, args[i]); + } + } else if (arg.equals(STATS)) { + env.messages.setStatsEnabled(true); + } else if (arg.matches("-bootclasspath") && i + 1 < args.length) { + javacBootClassPath = splitPath(args[++i]); + } else if (arg.matches("-classpath") && i + 1 < args.length) { + javacClassPath = splitPath(args[++i]); + } else if (arg.matches("-sourcepath") && i + 1 < args.length) { + javacSourcePath = splitPath(args[++i]); + } else if (arg.equals(XMSGS_OPTION)) { + env.messages.setOptions(null); + } else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) { + env.messages.setOptions(arg.substring(arg.indexOf(":") + 1)); + } else if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help") + || arg.equals("-?") || arg.equals("-usage")) { + needHelp = true; + } else if (arg.startsWith("-")) { + throw new BadArgs("dc.bad.option", arg); + } else { + while (i < args.length) + javacFiles.add(new File(args[i++])); + } + } + } + + void showHelp(PrintWriter out) { + out.println("Usage:"); + out.println(" doclint [options] source-files..."); + out.println(""); + out.println("Options:"); + out.println(" -Xmsgs "); + out.println(" Same as -Xmsgs:all"); + out.println(" -Xmsgs:values"); + out.println(" Specify categories of issues to be checked, where 'values'"); + out.println(" is a comma-separated list of any of the following:"); + out.println(" reference show places where comments contain incorrect"); + out.println(" references to Java source code elements"); + out.println(" syntax show basic syntax errors within comments"); + out.println(" html show issues with HTML tags and attributes"); + out.println(" accessibility show issues for accessibility"); + out.println(" missing show issues with missing documentation"); + out.println(" all all of the above"); + out.println(" Precede a value with '-' to negate it"); + out.println(" Categories may be qualified by one of:"); + out.println(" /public /protected /package /private"); + out.println(" For positive categories (not beginning with '-')"); + out.println(" the qualifier applies to that access level and above."); + out.println(" For negative categories (beginning with '-')"); + out.println(" the qualifier applies to that access level and below."); + out.println(" If a qualifier is missing, the category applies to"); + out.println(" all access levels."); + out.println(" For example, -Xmsgs:all,-syntax/private"); + out.println(" This will enable all messages, except syntax errors"); + out.println(" in the doc comments of private methods."); + out.println(" If no -Xmsgs options are provided, the default is"); + out.println(" equivalent to -Xmsgs:all/protected, meaning that"); + out.println(" all messages are reported for protected and public"); + out.println(" declarations only. "); + out.println(" -h -help --help -usage -?"); + out.println(" Show this message."); + out.println(""); + out.println("The following javac options are also supported"); + out.println(" -bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns"); + out.println(""); + out.println("To run doclint on part of a project, put the compiled classes for your"); + out.println("project on the classpath (or bootclasspath), then specify the source files"); + out.println("to be checked on the command line."); + } + + List splitPath(String path) { + List files = new ArrayList(); + for (String f: path.split(File.separator)) { + if (f.length() > 0) + files.add(new File(f)); + } + return files; + } + + List javacBootClassPath; + List javacClassPath; + List javacSourcePath; + List javacOpts; + List javacFiles; + boolean needHelp = false; + + // + + // + + @Override + public String getName() { + return "doclint"; + } + + @Override + public void init(JavacTask task, String... args) { + init(task, args, true); + } + + // + + // + + public void init(JavacTask task, String[] args, boolean addTaskListener) { + env = new Env(); + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (arg.equals(XMSGS_OPTION)) { + env.messages.setOptions(null); + } else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) { + env.messages.setOptions(arg.substring(arg.indexOf(":") + 1)); + } else + throw new IllegalArgumentException(arg); + } + env.init(task); + + checker = new Checker(env); + + if (addTaskListener) { + final DeclScanner ds = new DeclScanner() { + @Override + void visitDecl(Tree tree, Name name) { + TreePath p = getCurrentPath(); + DocCommentTree dc = env.trees.getDocCommentTree(p); + + checker.scan(dc, p); + } + }; + + TaskListener tl = new TaskListener() { + @Override + public void started(TaskEvent e) { + return; + } + + @Override + public void finished(TaskEvent e) { + switch (e.getKind()) { + case ENTER: + ds.scan(e.getCompilationUnit(), null); + } + } + }; + + task.addTaskListener(tl); + } + } + + public void scan(TreePath p) { + DocCommentTree dc = env.trees.getDocCommentTree(p); + checker.scan(dc, p); + } + + public void reportStats(PrintWriter out) { + env.messages.reportStats(out); + } + + // + + Env env; + Checker checker; + + public static boolean isValidOption(String opt) { + if (opt.equals(XMSGS_OPTION)) + return true; + if (opt.startsWith(XMSGS_CUSTOM_PREFIX)) + return Messages.Options.isValidOptions(opt.substring(XMSGS_CUSTOM_PREFIX.length())); + return false; + } + + // + + static abstract class DeclScanner extends TreePathScanner { + abstract void visitDecl(Tree tree, Name name); + + @Override + public Void visitClass(ClassTree tree, Void ignore) { + visitDecl(tree, tree.getSimpleName()); + return super.visitClass(tree, ignore); + } + + @Override + public Void visitMethod(MethodTree tree, Void ignore) { + visitDecl(tree, tree.getName()); + //return super.visitMethod(tree, ignore); + return null; + } + + @Override + public Void visitVariable(VariableTree tree, Void ignore) { + visitDecl(tree, tree.getName()); + return super.visitVariable(tree, ignore); + } + } + + // + +} diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/Entity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/Entity.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclint; + +import java.util.HashMap; +import java.util.Map; + +/** + * Table of entities defined in HTML 4.01. + * + *

Derived from + * Character entity references in HTML 4. + * + * The name of the member follows the name of the entity, + * except when it clashes with a keyword, in which case + * it is prefixed by '_'. + * + *

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.

+ */ +enum Entity { + nbsp(160), + iexcl(161), + cent(162), + pound(163), + curren(164), + yen(165), + brvbar(166), + sect(167), + uml(168), + copy(169), + ordf(170), + laquo(171), + not(172), + shy(173), + reg(174), + macr(175), + deg(176), + plusmn(177), + sup2(178), + sup3(179), + acute(180), + micro(181), + para(182), + middot(183), + cedil(184), + sup1(185), + ordm(186), + raquo(187), + frac14(188), + frac12(189), + frac34(190), + iquest(191), + Agrave(192), + Aacute(193), + Acirc(194), + Atilde(195), + Auml(196), + Aring(197), + AElig(198), + Ccedil(199), + Egrave(200), + Eacute(201), + Ecirc(202), + Euml(203), + Igrave(204), + Iacute(205), + Icirc(206), + Iuml(207), + ETH(208), + Ntilde(209), + Ograve(210), + Oacute(211), + Ocirc(212), + Otilde(213), + Ouml(214), + times(215), + Oslash(216), + Ugrave(217), + Uacute(218), + Ucirc(219), + Uuml(220), + Yacute(221), + THORN(222), + szlig(223), + agrave(224), + aacute(225), + acirc(226), + atilde(227), + auml(228), + aring(229), + aelig(230), + ccedil(231), + egrave(232), + eacute(233), + ecirc(234), + euml(235), + igrave(236), + iacute(237), + icirc(238), + iuml(239), + eth(240), + ntilde(241), + ograve(242), + oacute(243), + ocirc(244), + otilde(245), + ouml(246), + divide(247), + oslash(248), + ugrave(249), + uacute(250), + ucirc(251), + uuml(252), + yacute(253), + thorn(254), + yuml(255), + fnof(402), + Alpha(913), + Beta(914), + Gamma(915), + Delta(916), + Epsilon(917), + Zeta(918), + Eta(919), + Theta(920), + Iota(921), + Kappa(922), + Lambda(923), + Mu(924), + Nu(925), + Xi(926), + Omicron(927), + Pi(928), + Rho(929), + Sigma(931), + Tau(932), + Upsilon(933), + Phi(934), + Chi(935), + Psi(936), + Omega(937), + alpha(945), + beta(946), + gamma(947), + delta(948), + epsilon(949), + zeta(950), + eta(951), + theta(952), + iota(953), + kappa(954), + lambda(955), + mu(956), + nu(957), + xi(958), + omicron(959), + pi(960), + rho(961), + sigmaf(962), + sigma(963), + tau(964), + upsilon(965), + phi(966), + chi(967), + psi(968), + omega(969), + thetasym(977), + upsih(978), + piv(982), + bull(8226), + hellip(8230), + prime(8242), + Prime(8243), + oline(8254), + frasl(8260), + weierp(8472), + image(8465), + real(8476), + trade(8482), + alefsym(8501), + larr(8592), + uarr(8593), + rarr(8594), + darr(8595), + harr(8596), + crarr(8629), + lArr(8656), + uArr(8657), + rArr(8658), + dArr(8659), + hArr(8660), + forall(8704), + part(8706), + exist(8707), + empty(8709), + nabla(8711), + isin(8712), + notin(8713), + ni(8715), + prod(8719), + sum(8721), + minus(8722), + lowast(8727), + radic(8730), + prop(8733), + infin(8734), + ang(8736), + and(8743), + or(8744), + cap(8745), + cup(8746), + _int(8747), + there4(8756), + sim(8764), + cong(8773), + asymp(8776), + ne(8800), + equiv(8801), + le(8804), + ge(8805), + sub(8834), + sup(8835), + nsub(8836), + sube(8838), + supe(8839), + oplus(8853), + otimes(8855), + perp(8869), + sdot(8901), + lceil(8968), + rceil(8969), + lfloor(8970), + rfloor(8971), + lang(9001), + rang(9002), + loz(9674), + spades(9824), + clubs(9827), + hearts(9829), + diams(9830), + quot(34), + amp(38), + lt(60), + gt(62), + OElig(338), + oelig(339), + Scaron(352), + scaron(353), + Yuml(376), + circ(710), + tilde(732), + ensp(8194), + emsp(8195), + thinsp(8201), + zwnj(8204), + zwj(8205), + lrm(8206), + rlm(8207), + ndash(8211), + mdash(8212), + lsquo(8216), + rsquo(8217), + sbquo(8218), + ldquo(8220), + rdquo(8221), + bdquo(8222), + dagger(8224), + Dagger(8225), + permil(8240), + lsaquo(8249), + rsaquo(8250), + euro(8364); + + int code; + + private Entity(int code) { + this.code = code; + } + + static boolean isValid(String name) { + return names.containsKey(name); + } + + static boolean isValid(int code) { + // allow numeric codes for standard ANSI characters + return codes.containsKey(code) || ( 32 <= code && code < 2127); + } + + private static final Map names = new HashMap(); + private static final Map codes = new HashMap(); + static { + for (Entity e: values()) { + String name = e.name(); + int code = e.code; + if (name.startsWith("_")) name = name.substring(1); + names.put(name, e); + codes.put(code, e); + } + } +} diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/Env.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/Env.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclint; + + +import java.util.Set; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.util.DocTrees; +import com.sun.source.util.JavacTask; +import com.sun.source.util.SourcePositions; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.model.JavacTypes; +import com.sun.tools.javac.tree.JCTree; + +/** + * Utility container for current execution environment, + * providing the current declaration and its doc comment. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class Env { + /** + * Access kinds for declarations. + */ + public enum AccessKind { + PRIVATE, + PACKAGE, + PROTECTED, + PUBLIC; + + static boolean accepts(String opt) { + for (AccessKind g: values()) + if (opt.equals(g.name().toLowerCase())) return true; + return false; + } + + static AccessKind of(Set mods) { + if (mods.contains(Modifier.PUBLIC)) + return AccessKind.PUBLIC; + else if (mods.contains(Modifier.PROTECTED)) + return AccessKind.PROTECTED; + else if (mods.contains(Modifier.PRIVATE)) + return AccessKind.PRIVATE; + else + return AccessKind.PACKAGE; + } + }; + + /** Message handler. */ + final Messages messages; + + // Utility classes + DocTrees trees; + Elements elements; + Types types; + + // Types used when analysing doc comments. + TypeMirror java_lang_Error; + TypeMirror java_lang_RuntimeException; + TypeMirror java_lang_Throwable; + TypeMirror java_lang_Void; + + /** The path for the declaration containing the comment currently being analyzed. */ + TreePath currPath; + /** The element for the declaration containing the comment currently being analyzed. */ + Element currElement; + /** The comment current being analyzed. */ + DocCommentTree currDocComment; + /** + * The access kind of the declaration containing the comment currently being analyzed. + * This is the minimum (most restrictive) access kind of the declaration iteself + * and that of its containers. For example, a public method in a private class is + * noted as private. + */ + AccessKind currAccess; + /** The set of methods, if any, that the current declaration overrides. */ + Set currOverriddenMethods; + + Env() { + messages = new Messages(this); + } + + void init(JavacTask task) { + init(DocTrees.instance(task), task.getElements(), task.getTypes()); + } + + void init(DocTrees trees, Elements elements, Types types) { + this.trees = trees; + this.elements = elements; + this.types = types; + java_lang_Error = elements.getTypeElement("java.lang.Error").asType(); + java_lang_RuntimeException = elements.getTypeElement("java.lang.RuntimeException").asType(); + java_lang_Throwable = elements.getTypeElement("java.lang.Throwable").asType(); + java_lang_Void = elements.getTypeElement("java.lang.Void").asType(); + } + + /** Set the current declaration and its doc comment. */ + void setCurrent(TreePath path, DocCommentTree comment) { + currPath = path; + currDocComment = comment; + currElement = trees.getElement(currPath); + currOverriddenMethods = ((JavacTypes) types).getOverriddenMethods(currElement); + + AccessKind ak = null; + for (TreePath p = path; p != null; p = p.getParentPath()) { + Element e = trees.getElement(p); + if (e != null) { + ak = min(ak, AccessKind.of(e.getModifiers())); + } + } + currAccess = ak; + } + + AccessKind getAccessKind() { + return currAccess; + } + + long getPos(TreePath p) { + return ((JCTree) p.getLeaf()).pos; + } + + long getStartPos(TreePath p) { + SourcePositions sp = trees.getSourcePositions(); + return sp.getStartPosition(p.getCompilationUnit(), p.getLeaf()); + } + + private > T min(T item1, T item2) { + return (item1 == null) ? item2 + : (item2 == null) ? item1 + : item1.compareTo(item2) <= 0 ? item1 : item2; + } +} diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/HtmlTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/HtmlTag.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2010, 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.doclint; + +import java.util.Set; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +import javax.lang.model.element.Name; + +import static com.sun.tools.doclint.HtmlTag.Attr.*; + +/** + * Enum representing HTML tags. + * + * The intent of this class is to embody the semantics of W3C HTML 4.01 + * to the extent supported/used by javadoc. + * + * This is derivative of com.sun.tools.doclets.formats.html.markup.HtmlTag. + * Eventually, these two should be merged back together, and possibly made + * public. + * + * @see HTML 4.01 Specification + * @author Bhavesh Patel + * @author Jonathan Gibbons (revised) + */ +public enum HtmlTag { + A(BlockType.INLINE, EndKind.REQUIRED, + attrs(AttrKind.OK, HREF, TARGET, NAME)), + + B(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + BLOCKQUOTE, + + BODY(BlockType.OTHER, EndKind.REQUIRED), + + BR(BlockType.INLINE, EndKind.NONE, + attrs(AttrKind.USE_CSS, CLEAR)), + + CAPTION(EnumSet.of(Flag.EXPECT_CONTENT)), + + CENTER, + + CITE(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + CODE(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + DD(BlockType.BLOCK, EndKind.OPTIONAL, + EnumSet.of(Flag.EXPECT_CONTENT)), + + DIV, + + DL(BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT), + attrs(AttrKind.USE_CSS, COMPACT)), + + DT(BlockType.BLOCK, EndKind.OPTIONAL, + EnumSet.of(Flag.EXPECT_CONTENT)), + + EM(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.NO_NEST)), + + FONT(BlockType.INLINE, EndKind.REQUIRED, // tag itself is deprecated + EnumSet.of(Flag.EXPECT_CONTENT), + attrs(AttrKind.USE_CSS, SIZE, COLOR, FACE)), + + FRAME(BlockType.OTHER, EndKind.NONE), + + FRAMESET(BlockType.OTHER, EndKind.REQUIRED), + + H1, + H2, + H3, + H4, + H5, + H6, + + HEAD(BlockType.OTHER, EndKind.REQUIRED), + + HR(BlockType.BLOCK, EndKind.NONE), + + HTML(BlockType.OTHER, EndKind.REQUIRED), + + I(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + IMG(BlockType.INLINE, EndKind.NONE, + attrs(AttrKind.OK, SRC, ALT, HEIGHT, WIDTH), + attrs(AttrKind.OBSOLETE, NAME), + attrs(AttrKind.USE_CSS, ALIGN, HSPACE, VSPACE, BORDER)), + + LI(BlockType.BLOCK, EndKind.OPTIONAL), + + LINK(BlockType.OTHER, EndKind.NONE), + + MENU, + + META(BlockType.OTHER, EndKind.NONE), + + NOFRAMES(BlockType.OTHER, EndKind.REQUIRED), + + NOSCRIPT(BlockType.OTHER, EndKind.REQUIRED), + + OL(BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT), + attrs(AttrKind.USE_CSS, START, TYPE)), + + P(BlockType.BLOCK, EndKind.OPTIONAL, + EnumSet.of(Flag.EXPECT_CONTENT), + attrs(AttrKind.USE_CSS, ALIGN)), + + PRE(EnumSet.of(Flag.EXPECT_CONTENT)), + + SCRIPT(BlockType.OTHER, EndKind.REQUIRED), + + SMALL(BlockType.INLINE, EndKind.REQUIRED), + + SPAN(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT)), + + STRONG(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT)), + + SUB(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + SUP(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + TABLE(BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT), + attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER, + CELLPADDING, CELLSPACING), + attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)), + + TBODY(BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT), + attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)), + + TD(BlockType.BLOCK, EndKind.OPTIONAL, + attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS, + ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)), + + TFOOT(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)), + + TH(BlockType.BLOCK, EndKind.OPTIONAL, + attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS, + ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)), + + THEAD(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)), + + TITLE(BlockType.OTHER, EndKind.REQUIRED), + + TR(BlockType.BLOCK, EndKind.OPTIONAL, + EnumSet.of(Flag.NO_TEXT), + attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.USE_CSS, BGCOLOR)), + + TT(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + U(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + + UL(BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT), + attrs(AttrKind.USE_CSS, COMPACT, TYPE)), + + VAR(BlockType.INLINE, EndKind.REQUIRED); + + /** + * Enum representing the type of HTML element. + */ + public static enum BlockType { + BLOCK, + INLINE, + OTHER; + } + + /** + * Enum representing HTML end tag requirement. + */ + public static enum EndKind { + NONE, + OPTIONAL, + REQUIRED; + } + + public static enum Flag { + EXPECT_CONTENT, + NO_NEST, + NO_TEXT + } + + public static enum Attr { + ABBR, + ALIGN, + ALT, + AXIS, + BGCOLOR, + BORDER, + CELLSPACING, + CELLPADDING, + CHAR, + CHAROFF, + CLEAR, + CLASS, + COLOR, + COLSPAN, + COMPACT, + FACE, + FRAME, + HEADERS, + HEIGHT, + HREF, + HSPACE, + ID, + NAME, + NOWRAP, + REVERSED, + ROWSPAN, + RULES, + SCOPE, + SIZE, + SPACE, + SRC, + START, + STYLE, + SUMMARY, + TARGET, + TYPE, + VALIGN, + VSPACE, + WIDTH; + + public String getText() { + return name().toLowerCase(); + } + + static final Map index = new HashMap(); + static { + for (Attr t: values()) { + index.put(t.name().toLowerCase(), t); + } + } + } + + public static enum AttrKind { + INVALID, + OBSOLETE, + USE_CSS, + OK + } + + // This class exists to avoid warnings from using parameterized vararg type + // Map in signature of HtmlTag constructor. + private static class AttrMap extends EnumMap { + private static final long serialVersionUID = 0; + AttrMap() { + super(Attr.class); + } + } + + + public final BlockType blockType; + public final EndKind endKind; + public final Set flags; + private final Map attrs; + + + HtmlTag() { + this(BlockType.BLOCK, EndKind.REQUIRED); + } + + HtmlTag(Set flags) { + this(BlockType.BLOCK, EndKind.REQUIRED, flags); + } + + HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) { + this(blockType, endKind, Collections.emptySet(), attrMaps); + } + + HtmlTag(BlockType blockType, EndKind endKind, Set flags, AttrMap... attrMaps) { + this.blockType = blockType; + this.endKind = endKind;this.flags = flags; + this.attrs = new EnumMap(Attr.class); + for (Map m: attrMaps) + this.attrs.putAll(m); + attrs.put(Attr.CLASS, AttrKind.OK); + attrs.put(Attr.ID, AttrKind.OK); + attrs.put(Attr.STYLE, AttrKind.OK); + } + + public String getText() { + return name().toLowerCase(); + } + + public Attr getAttr(Name attrName) { + return Attr.index.get(attrName.toString().toLowerCase()); + } + + public AttrKind getAttrKind(Name attrName) { + AttrKind k = attrs.get(getAttr(attrName)); // null-safe + return (k == null) ? AttrKind.INVALID : k; + } + + private static AttrMap attrs(AttrKind k, Attr... attrs) { + AttrMap map = new AttrMap(); + for (Attr a: attrs) map.put(a, k); + return map; + } + + private static final Map index = new HashMap(); + static { + for (HtmlTag t: values()) { + index.put(t.name().toLowerCase(), t); + } + } + + static HtmlTag get(Name tagName) { + return index.get(tagName.toString().toLowerCase()); + } +} diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/Messages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/Messages.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclint; + +import java.io.PrintWriter; +import java.text.MessageFormat; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import javax.tools.Diagnostic; + +import com.sun.source.doctree.DocTree; +import com.sun.source.tree.Tree; +import com.sun.tools.doclint.Env.AccessKind; + +/** + * Message reporting for DocLint. + * + * Options are used to filter out messages based on group and access level. + * Support can be enabled for accumulating statistics of different kinds of + * messages. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class Messages { + /** + * Groups used to categorize messages, so that messages in each group + * can be enabled or disabled via options. + */ + public enum Group { + ACCESSIBILITY, + HTML, + MISSING, + SYNTAX, + REFERENCE; + + String optName() { return name().toLowerCase(); } + String notOptName() { return "-" + optName(); } + + static boolean accepts(String opt) { + for (Group g: values()) + if (opt.equals(g.optName())) return true; + return false; + } + }; + + private final Options options; + private final Stats stats; + + ResourceBundle bundle; + Env env; + + Messages(Env env) { + this.env = env; + String name = getClass().getPackage().getName() + ".resources.doclint"; + bundle = ResourceBundle.getBundle(name, Locale.ENGLISH); + + stats = new Stats(bundle); + options = new Options(stats); + } + + void error(Group group, DocTree tree, String code, Object... args) { + report(group, Diagnostic.Kind.ERROR, tree, code, args); + } + + void warning(Group group, DocTree tree, String code, Object... args) { + report(group, Diagnostic.Kind.WARNING, tree, code, args); + } + + void setOptions(String opts) { + options.setOptions(opts); + } + + void setStatsEnabled(boolean b) { + stats.setEnabled(b); + } + + void reportStats(PrintWriter out) { + stats.report(out); + } + + protected void report(Group group, Diagnostic.Kind dkind, DocTree tree, String code, Object... args) { + if (options.isEnabled(group, env.currAccess)) { + String msg = (code == null) ? (String) args[0] : localize(code, args); + env.trees.printMessage(dkind, msg, tree, + env.currDocComment, env.currPath.getCompilationUnit()); + + stats.record(group, dkind, code); + } + } + + protected void report(Group group, Diagnostic.Kind dkind, Tree tree, String code, Object... args) { + if (options.isEnabled(group, env.currAccess)) { + String msg = localize(code, args); + env.trees.printMessage(dkind, msg, tree, env.currPath.getCompilationUnit()); + + stats.record(group, dkind, code); + } + } + + String localize(String code, Object... args) { + String msg = bundle.getString(code); + if (msg == null) { + StringBuilder sb = new StringBuilder(); + sb.append("message file broken: code=").append(code); + if (args.length > 0) { + sb.append(" arguments={0}"); + for (int i = 1; i < args.length; i++) { + sb.append(", {").append(i).append("}"); + } + } + msg = sb.toString(); + } + return MessageFormat.format(msg, args); + } + + // + + /** + * Handler for (sub)options specific to message handling. + */ + static class Options { + Map map = new HashMap(); + private final Stats stats; + + static boolean isValidOptions(String opts) { + for (String opt: opts.split(",")) { + if (!isValidOption(opt.trim().toLowerCase())) + return false; + } + return true; + } + + private static boolean isValidOption(String opt) { + if (opt.equals("none") || opt.equals(Stats.OPT)) + return true; + + int begin = opt.startsWith("-") ? 1 : 0; + int sep = opt.indexOf("/"); + String grp = opt.substring(begin, (sep != -1) ? sep : opt.length()); + return ((begin == 0 && grp.equals("all")) || Group.accepts(grp)) + && ((sep == -1) || AccessKind.accepts(opt.substring(sep + 1))); + } + + Options(Stats stats) { + this.stats = stats; + } + + /** Determine if a message group is enabled for a particular access level. */ + boolean isEnabled(Group g, Env.AccessKind access) { + if (map.isEmpty()) + map.put("all", Env.AccessKind.PROTECTED); + + Env.AccessKind ak = map.get(g.optName()); + if (ak != null && access.compareTo(ak) >= 0) + return true; + + ak = map.get(ALL); + if (ak != null && access.compareTo(ak) >= 0) { + ak = map.get(g.notOptName()); + if (ak == null || access.compareTo(ak) > 0) // note >, not >= + return true; + } + + return false; + } + + void setOptions(String opts) { + if (opts == null) + setOption(ALL, Env.AccessKind.PRIVATE); + else { + for (String opt: opts.split(",")) + setOption(opt.trim().toLowerCase()); + } + } + + private void setOption(String arg) throws IllegalArgumentException { + if (arg.equals(Stats.OPT)) { + stats.setEnabled(true); + return; + } + + int sep = arg.indexOf("/"); + if (sep > 0) { + Env.AccessKind ak = Env.AccessKind.valueOf(arg.substring(sep + 1).toUpperCase()); + setOption(arg.substring(0, sep), ak); + } else { + setOption(arg, null); + } + } + + private void setOption(String opt, Env.AccessKind ak) { + map.put(opt, (ak != null) ? ak + : opt.startsWith("-") ? Env.AccessKind.PUBLIC : Env.AccessKind.PRIVATE); + } + + private static final String ALL = "all"; + } + + // + + // + + /** + * Optionally record statistics of different kinds of message. + */ + static class Stats { + public static final String OPT = "stats"; + public static final String NO_CODE = ""; + final ResourceBundle bundle; + + // tables only initialized if enabled + int[] groupCounts; + int[] dkindCounts; + Map codeCounts; + + Stats(ResourceBundle bundle) { + this.bundle = bundle; + } + + void setEnabled(boolean b) { + if (b) { + groupCounts = new int[Messages.Group.values().length]; + dkindCounts = new int[Diagnostic.Kind.values().length]; + codeCounts = new HashMap(); + } else { + groupCounts = null; + dkindCounts = null; + codeCounts = null; + } + } + + void record(Messages.Group g, Diagnostic.Kind dkind, String code) { + if (codeCounts == null) { + return; + } + groupCounts[g.ordinal()]++; + dkindCounts[dkind.ordinal()]++; + if (code == null) { + code = NO_CODE; + } + Integer i = codeCounts.get(code); + codeCounts.put(code, (i == null) ? 1 : i + 1); + } + + void report(PrintWriter out) { + if (codeCounts == null) { + return; + } + out.println("By group..."); + Table groupTable = new Table(); + for (Messages.Group g : Messages.Group.values()) { + groupTable.put(g.optName(), groupCounts[g.ordinal()]); + } + groupTable.print(out); + out.println(); + out.println("By diagnostic kind..."); + Table dkindTable = new Table(); + for (Diagnostic.Kind k : Diagnostic.Kind.values()) { + dkindTable.put(k.toString().toLowerCase(), dkindCounts[k.ordinal()]); + } + dkindTable.print(out); + out.println(); + out.println("By message kind..."); + Table codeTable = new Table(); + for (Map.Entry e : codeCounts.entrySet()) { + String code = e.getKey(); + String msg; + try { + msg = code.equals(NO_CODE) ? "OTHER" : bundle.getString(code); + } catch (MissingResourceException ex) { + msg = code; + } + codeTable.put(msg, e.getValue()); + } + codeTable.print(out); + } + + /** + * A table of (int, String) sorted by decreasing int. + */ + private static class Table { + + private static final Comparator DECREASING = new Comparator() { + + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + }; + private final TreeMap> map = new TreeMap>(DECREASING); + + void put(String label, int n) { + if (n == 0) { + return; + } + Set labels = map.get(n); + if (labels == null) { + map.put(n, labels = new TreeSet()); + } + labels.add(label); + } + + void print(PrintWriter out) { + for (Map.Entry> e : map.entrySet()) { + int count = e.getKey(); + Set labels = e.getValue(); + for (String label : labels) { + out.println(String.format("%6d: %s", count, label)); + } + } + } + } + } + // +} diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/doclint/resources/doclint.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,65 @@ +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +dc.anchor.already.defined = anchor already defined: {0} +dc.attr.lacks.value = attribute lacks value +dc.attr.obsolete = attribute obsolete: {0} +dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0} +dc.attr.repeated = repeated attribute: {0} +dc.attr.unknown = unknown attribute: {0} +dc.bad.option = bad option: {0} +dc.bad.value.for.option = bad value for option: {0} {1} +dc.empty = no description for @{0} +dc.entity.invalid = invalid entity &{0}; +dc.exception.not.thrown = exception not thrown: {0} +dc.invalid.anchor = invalid name for anchor: "{0}" +dc.invalid.param = invalid use of @param +dc.invalid.return = invalid use of @return +dc.invalid.throws = invalid use of @throws +dc.invalid.uri = invalid uri: "{0}" +dc.missing.comment = no comment +dc.missing.param = no @param for {0} +dc.missing.return = no @return +dc.missing.throws = no @throws for {0} +dc.no.alt.attr.for.image = no "alt" attribute for image +dc.no.summary.or.caption.for.table=no summary or caption for table +dc.param.name.not.found = @param name not found +dc.ref.not.found = reference not found +dc.tag.empty = empty <{0}> tag +dc.tag.end.not.permitted = invalid end tag: +dc.tag.end.unexpected = unexpected end tag: +dc.tag.header.sequence.1 = header used out of sequence: <{0}> +dc.tag.header.sequence.2 = header used out of sequence: <{0}> +dc.tag.nested.not.allowed=nested tag not allowed: <{0}> +dc.tag.not.allowed = element not allowed in documentation comments: <{0}> +dc.tag.not.allowed.inline.element = block element not allowed within inline element <{1}>: {0} +dc.tag.not.allowed.inline.tag = block element not allowed within @{1}: {0} +dc.tag.not.allowed.inline.other = block element not allowed here: {0} +dc.tag.not.closed= element not closed: {0} +dc.tag.p.in.pre= unexpected use of

inside

 element
+dc.tag.self.closing = self-closing element not allowed
+dc.tag.start.unmatched = end tag missing: 
+dc.tag.unknown = unknown tag: {0}
+dc.text.not.allowed = text not allowed in <{0}> element
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java
--- a/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java	Fri Dec 28 18:39:09 2012 -0800
@@ -57,6 +57,13 @@
     protected Context context;
     private TaskListener taskListener;
 
+    public static JavacTask instance(Context context) {
+        JavacTask instance = context.get(JavacTask.class);
+        if (instance == null)
+            instance = new BasicJavacTask(context, true);
+        return instance;
+    }
+
     public BasicJavacTask(Context c, boolean register) {
         context = c;
         if (register)
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java
--- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -65,7 +65,6 @@
  * @author Jonathan Gibbons
  */
 public class JavacTaskImpl extends BasicJavacTask {
-    private ClientCodeWrapper ccw;
     private Main compilerMain;
     private JavaCompiler compiler;
     private Locale locale;
@@ -85,7 +84,6 @@
                 Context context,
                 List fileObjects) {
         super(null, false);
-        this.ccw = ClientCodeWrapper.instance(context);
         this.compilerMain = compilerMain;
         this.args = args;
         this.classNames = classNames;
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/api/JavacTool.java
--- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Fri Dec 28 18:39:09 2012 -0800
@@ -159,7 +159,7 @@
         }
     }
 
-    private static void processOptions(Context context,
+    public static void processOptions(Context context,
                                        JavaFileManager fileManager,
                                        Iterable options)
     {
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/api/JavacTrees.java
--- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Fri Dec 28 18:39:09 2012 -0800
@@ -84,6 +84,7 @@
 import com.sun.tools.javac.tree.TreeCopier;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.util.Abort;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.JCDiagnostic;
@@ -236,19 +237,26 @@
     public Element getElement(TreePath path) {
         JCTree tree = (JCTree) path.getLeaf();
         Symbol sym = TreeInfo.symbolFor(tree);
-        if (sym == null && TreeInfo.isDeclaration(tree)) {
-            for (TreePath p = path; p != null; p = p.getParentPath()) {
-                JCTree t = (JCTree) p.getLeaf();
-                if (t.hasTag(JCTree.Tag.CLASSDEF)) {
-                    JCClassDecl ct = (JCClassDecl) t;
-                    if (ct.sym != null) {
-                        if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) {
-                            attr.attribClass(ct.pos(), ct.sym);
-                            sym = TreeInfo.symbolFor(tree);
+        if (sym == null) {
+            if (TreeInfo.isDeclaration(tree)) {
+                for (TreePath p = path; p != null; p = p.getParentPath()) {
+                    JCTree t = (JCTree) p.getLeaf();
+                    if (t.hasTag(JCTree.Tag.CLASSDEF)) {
+                        JCClassDecl ct = (JCClassDecl) t;
+                        if (ct.sym != null) {
+                            if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) {
+                                attr.attribClass(ct.pos(), ct.sym);
+                                sym = TreeInfo.symbolFor(tree);
+                            }
+                            break;
                         }
-                        break;
                     }
                 }
+            } else if (tree.hasTag(Tag.TOPLEVEL)) {
+                JCCompilationUnit cu = (JCCompilationUnit) tree;
+                if (cu.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) {
+                    sym = cu.packge;
+                }
             }
         }
         return sym;
@@ -332,6 +340,8 @@
             } else {
                 return msym;
             }
+        } catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
+            return null;
         } finally {
             log.popDiagnosticHandler(deferredDiagnosticHandler);
         }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/code/Attribute.java
--- a/src/share/classes/com/sun/tools/javac/code/Attribute.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri Dec 28 18:39:09 2012 -0800
@@ -60,6 +60,9 @@
         throw new UnsupportedOperationException();
     }
 
+    public boolean isSynthesized() {
+        return false;
+    }
 
     /** The value for an annotation element of primitive type or String. */
     public static class Constant extends Attribute {
@@ -136,6 +139,18 @@
          *  access this attribute.
          */
         public final List> values;
+
+        private boolean synthesized = false;
+
+        @Override
+        public boolean isSynthesized() {
+            return synthesized;
+        }
+
+        public void setSynthesized(boolean synthesized) {
+            this.synthesized = synthesized;
+        }
+
         public Compound(Type type,
                         List> values) {
             super(type);
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/code/Symbol.java
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Dec 28 18:39:09 2012 -0800
@@ -83,13 +83,13 @@
      *  Attributes of class symbols should be accessed through the accessor
      *  method to make sure that the class symbol is loaded.
      */
-    public List getAnnotationMirrors() {
-        return Assert.checkNonNull(annotations.getAttributes());
+    public List getRawAttributes() {
+        return annotations.getAttributes();
     }
 
     /** Fetch a particular annotation from a symbol. */
     public Attribute.Compound attribute(Symbol anno) {
-        for (Attribute.Compound a : getAnnotationMirrors()) {
+        for (Attribute.Compound a : getRawAttributes()) {
             if (a.type.tsym == anno) return a;
         }
         return null;
@@ -447,6 +447,14 @@
     }
 
     /**
+     * This is the implementation for {@code
+     * javax.lang.model.element.Element.getAnnotationMirrors()}.
+     */
+    public final List getAnnotationMirrors() {
+        return getRawAttributes();
+    }
+
+    /**
      * @deprecated this method should never be used by javac internally.
      */
     @Deprecated
@@ -662,15 +670,21 @@
             return flags_field;
         }
 
-        public List getAnnotationMirrors() {
+        @Override
+        public List getRawAttributes() {
             if (completer != null) complete();
             if (package_info != null && package_info.completer != null) {
                 package_info.complete();
-                if (annotations.isEmpty()) {
-                    annotations.setAttributes(package_info.annotations);
+                mergeAttributes();
             }
+            return super.getRawAttributes();
+        }
+
+        private void mergeAttributes() {
+            if (annotations.isEmpty() &&
+                !package_info.annotations.isEmpty()) {
+                annotations.setAttributes(package_info.annotations);
             }
-            return Assert.checkNonNull(annotations.getAttributes());
         }
 
         /** A package "exists" if a type or package that exists has
@@ -770,9 +784,10 @@
             return members_field;
         }
 
-        public List getAnnotationMirrors() {
+        @Override
+        public List getRawAttributes() {
             if (completer != null) complete();
-            return Assert.checkNonNull(annotations.getAttributes());
+            return super.getRawAttributes();
         }
 
         public Type erasure(Types types) {
@@ -1353,7 +1368,7 @@
             return defaultValue;
         }
 
-        public List getParameters() {
+         public List getParameters() {
             return params();
         }
 
@@ -1361,6 +1376,10 @@
             return (flags() & VARARGS) != 0;
         }
 
+        public boolean isDefault() {
+            return (flags() & DEFAULT) != 0;
+        }
+
         public  R accept(ElementVisitor v, P p) {
             return v.visitExecutable(this, p);
         }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/code/Type.java
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Fri Dec 28 18:39:09 2012 -0800
@@ -302,10 +302,12 @@
      * never complete classes. Where isSameType would complete a
      * class, equals assumes that the two types are different.
      */
+    @Override
     public boolean equals(Object t) {
         return super.equals(t);
     }
 
+    @Override
     public int hashCode() {
         return super.hashCode();
     }
@@ -996,34 +998,6 @@
             return "(" + argtypes + ")" + restype;
         }
 
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (!(obj instanceof MethodType))
-                return false;
-            MethodType m = (MethodType)obj;
-            List args1 = argtypes;
-            List args2 = m.argtypes;
-            while (!args1.isEmpty() && !args2.isEmpty()) {
-                if (!args1.head.equals(args2.head))
-                    return false;
-                args1 = args1.tail;
-                args2 = args2.tail;
-            }
-            if (!args1.isEmpty() || !args2.isEmpty())
-                return false;
-            return restype.equals(m.restype);
-        }
-
-        public int hashCode() {
-            int h = METHOD.ordinal();
-            for (List thisargs = this.argtypes;
-                 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
-                 thisargs = thisargs.tail)
-                h = (h << 5) + thisargs.head.hashCode();
-            return (h << 5) + this.restype.hashCode();
-        }
-
         public List        getParameterTypes() { return argtypes; }
         public Type              getReturnType()     { return restype; }
         public List        getThrownTypes()    { return thrown; }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/code/Types.java
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Dec 28 18:39:09 2012 -0800
@@ -1007,11 +1007,11 @@
                     if (!visit(supertype(t), supertype(s)))
                         return false;
 
-                    HashSet set = new HashSet();
+                    HashSet set = new HashSet();
                     for (Type x : interfaces(t))
-                        set.add(new SingletonType(x));
+                        set.add(new UniqueType(x, Types.this));
                     for (Type x : interfaces(s)) {
-                        if (!set.remove(new SingletonType(x)))
+                        if (!set.remove(new UniqueType(x, Types.this)))
                             return false;
                     }
                     return (set.isEmpty());
@@ -3137,7 +3137,7 @@
             }
             @Override
             public int hashCode() {
-                return 127 * Types.hashCode(t1) + Types.hashCode(t2);
+                return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
             }
             @Override
             public boolean equals(Object obj) {
@@ -3400,7 +3400,7 @@
     /**
      * Compute a hash code on a type.
      */
-    public static int hashCode(Type t) {
+    public int hashCode(Type t) {
         return hashCode.visit(t);
     }
     // where
@@ -3423,6 +3423,16 @@
             }
 
             @Override
+            public Integer visitMethodType(MethodType t, Void ignored) {
+                int h = METHOD.ordinal();
+                for (List thisargs = t.argtypes;
+                     thisargs.tail != null;
+                     thisargs = thisargs.tail)
+                    h = (h << 5) + visit(thisargs.head);
+                return (h << 5) + visit(t.restype);
+            }
+
+            @Override
             public Integer visitWildcardType(WildcardType t, Void ignored) {
                 int result = t.kind.hashCode();
                 if (t.type != null) {
@@ -4082,21 +4092,28 @@
     /**
      * A wrapper for a type that allows use in sets.
      */
-    class SingletonType {
-        final Type t;
-        SingletonType(Type t) {
-            this.t = t;
+    public static class UniqueType {
+        public final Type type;
+        final Types types;
+
+        public UniqueType(Type type, Types types) {
+            this.type = type;
+            this.types = types;
         }
+
         public int hashCode() {
-            return Types.hashCode(t);
+            return types.hashCode(type);
         }
+
         public boolean equals(Object obj) {
-            return (obj instanceof SingletonType) &&
-                isSameType(t, ((SingletonType)obj).t);
+            return (obj instanceof UniqueType) &&
+                types.isSameType(type, ((UniqueType)obj).type);
         }
+
         public String toString() {
-            return t.toString();
+            return type.toString();
         }
+
     }
     // 
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/comp/Annotate.java
--- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Fri Dec 28 18:39:09 2012 -0800
@@ -400,6 +400,7 @@
             Attribute.Compound c = enterAnnotation(annoTree,
                                                    targetContainerType,
                                                    ctx.env);
+            c.setSynthesized(true);
             return c;
         } else {
             return null; // errors should have been reported elsewhere
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/comp/Attr.java
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Dec 28 18:39:09 2012 -0800
@@ -1405,7 +1405,8 @@
         Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
         if (condtype.constValue() != null &&
                 truetype.constValue() != null &&
-                falsetype.constValue() != null) {
+                falsetype.constValue() != null &&
+                !owntype.hasTag(NONE)) {
             //constant folding
             owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
         }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Dec 28 18:39:09 2012 -0800
@@ -692,8 +692,9 @@
         //determine the static bsm args
         Type mtype = makeFunctionalDescriptorType(targetType, true);
         List staticArgs = List.of(
-                new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(targetType.tsym)),
-                new Pool.MethodHandle(refKind, refSym),
+                new Pool.MethodHandle(ClassFile.REF_invokeInterface,
+                    types.findDescriptorSymbol(targetType.tsym), types),
+                new Pool.MethodHandle(refKind, refSym, types),
                 new MethodType(mtype.getParameterTypes(),
                         mtype.getReturnType(),
                         mtype.getThrownTypes(),
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/comp/Resolve.java
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Dec 28 18:39:09 2012 -0800
@@ -1798,6 +1798,9 @@
 
         if ((kind & TYP) != 0) {
             sym = findType(env, name);
+            if (sym.kind==TYP) {
+                 reportDependence(env.enclClass.sym, sym);
+            }
             if (sym.exists()) return sym;
             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
         }
@@ -1806,6 +1809,14 @@
         else return bestSoFar;
     }
 
+    /** Report dependencies.
+     * @param from The enclosing class sym
+     * @param to   The found identifier that the class depends on.
+     */
+    public void reportDependence(Symbol from, Symbol to) {
+        // Override if you want to collect the reported dependencies.
+    }
+
     /** Find an identifier in a package which matches a specified kind set.
      *  @param env       The current environment.
      *  @param name      The identifier's name.
@@ -3064,16 +3075,20 @@
             if (hasLocation) {
                 return diags.create(dkind, log.currentSource(), pos,
                         errKey, kindname, idname, //symbol kindname, name
-                        typeargtypes, argtypes, //type parameters and arguments (if any)
+                        typeargtypes, args(argtypes), //type parameters and arguments (if any)
                         getLocationDiag(location, site)); //location kindname, type
             }
             else {
                 return diags.create(dkind, log.currentSource(), pos,
                         errKey, kindname, idname, //symbol kindname, name
-                        typeargtypes, argtypes); //type parameters and arguments (if any)
+                        typeargtypes, args(argtypes)); //type parameters and arguments (if any)
             }
         }
         //where
+        private Object args(List args) {
+            return args.isEmpty() ? args : methodArguments(args);
+        }
+
         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
             String key = "cant.resolve";
             String suffix = hasLocation ? ".location" : "";
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java
--- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Fri Dec 28 18:39:09 2012 -0800
@@ -548,17 +548,15 @@
                 }
 
                 if (i >= 0) {
-                    zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2];
-                    zipDir[0] = endbuf[i + 10];
-                    zipDir[1] = endbuf[i + 11];
+                    zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12)];
                     int sz = get4ByteLittleEndian(endbuf, i + 16);
                     // a negative offset or the entries field indicates a
                     // potential zip64 archive
-                    if (sz < 0 || get2ByteLittleEndian(zipDir, 0) == 0xffff) {
+                    if (sz < 0 || get2ByteLittleEndian(endbuf, i + 10) == 0xffff) {
                         throw new ZipFormatException("detected a zip64 archive");
                     }
                     zipRandomFile.seek(start + sz);
-                    zipRandomFile.readFully(zipDir, 2, zipDir.length - 2);
+                    zipRandomFile.readFully(zipDir, 0, zipDir.length);
                     return;
                 } else {
                     endbufend = endbufpos + 21;
@@ -568,14 +566,13 @@
         }
 
         private void buildIndex() throws IOException {
-            int entryCount = get2ByteLittleEndian(zipDir, 0);
+            int len = zipDir.length;
 
             // Add each of the files
-            if (entryCount > 0) {
+            if (len > 0) {
                 directories = new LinkedHashMap();
                 ArrayList entryList = new ArrayList();
-                int pos = 2;
-                for (int i = 0; i < entryCount; i++) {
+                for (int pos = 0; pos < len; ) {
                     pos = readEntry(pos, entryList, directories);
                 }
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/ClassFile.java
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Fri Dec 28 18:39:09 2012 -0800
@@ -26,6 +26,8 @@
 package com.sun.tools.javac.jvm;
 
 import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.code.Types.UniqueType;
 import com.sun.tools.javac.util.Name;
 
 
@@ -166,22 +168,29 @@
      */
     public static class NameAndType {
         Name name;
-        Type type;
+        UniqueType uniqueType;
+        Types types;
 
-        NameAndType(Name name, Type type) {
+        NameAndType(Name name, Type type, Types types) {
             this.name = name;
-            this.type = type;
+            this.uniqueType = new UniqueType(type, types);
+            this.types = types;
         }
 
-        public boolean equals(Object other) {
-            return
-                other instanceof NameAndType &&
-                name == ((NameAndType) other).name &&
-                type.equals(((NameAndType) other).type);
+        void setType(Type type) {
+            this.uniqueType = new UniqueType(type, types);
         }
 
+        @Override
+        public boolean equals(Object other) {
+            return (other instanceof NameAndType &&
+                    name == ((NameAndType) other).name &&
+                        uniqueType.equals(((NameAndType) other).uniqueType));
+        }
+
+        @Override
         public int hashCode() {
-            return name.hashCode() * type.hashCode();
+            return name.hashCode() * uniqueType.hashCode();
         }
     }
 }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Dec 28 18:39:09 2012 -0800
@@ -488,20 +488,20 @@
         case CONSTANT_Fieldref: {
             ClassSymbol owner = readClassSymbol(getChar(index + 1));
             NameAndType nt = (NameAndType)readPool(getChar(index + 3));
-            poolObj[i] = new VarSymbol(0, nt.name, nt.type, owner);
+            poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner);
             break;
         }
         case CONSTANT_Methodref:
         case CONSTANT_InterfaceMethodref: {
             ClassSymbol owner = readClassSymbol(getChar(index + 1));
             NameAndType nt = (NameAndType)readPool(getChar(index + 3));
-            poolObj[i] = new MethodSymbol(0, nt.name, nt.type, owner);
+            poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner);
             break;
         }
         case CONSTANT_NameandType:
             poolObj[i] = new NameAndType(
                 readName(getChar(index + 1)),
-                readType(getChar(index + 3)));
+                readType(getChar(index + 3)), types);
             break;
         case CONSTANT_Integer:
             poolObj[i] = getInt(index + 1);
@@ -1224,7 +1224,7 @@
         if (nt == null)
             return null;
 
-        MethodType type = nt.type.asMethodType();
+        MethodType type = nt.uniqueType.type.asMethodType();
 
         for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())
             if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))
@@ -1236,16 +1236,16 @@
         if ((flags & INTERFACE) != 0)
             // no enclosing instance
             return null;
-        if (nt.type.getParameterTypes().isEmpty())
+        if (nt.uniqueType.type.getParameterTypes().isEmpty())
             // no parameters
             return null;
 
         // A constructor of an inner class.
         // Remove the first argument (the enclosing instance)
-        nt.type = new MethodType(nt.type.getParameterTypes().tail,
-                                 nt.type.getReturnType(),
-                                 nt.type.getThrownTypes(),
-                                 syms.methodClass);
+        nt.setType(new MethodType(nt.uniqueType.type.getParameterTypes().tail,
+                                 nt.uniqueType.type.getReturnType(),
+                                 nt.uniqueType.type.getThrownTypes(),
+                                 syms.methodClass));
         // Try searching again
         return findMethod(nt, scope, flags);
     }
@@ -1959,7 +1959,7 @@
 
         if (readAllOfClassFile) {
             for (int i = 1; i < poolObj.length; i++) readPool(i);
-            c.pool = new Pool(poolObj.length, poolObj);
+            c.pool = new Pool(poolObj.length, poolObj, types);
         }
 
         // reset and read rest of classinfo
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Dec 28 18:39:09 2012 -0800
@@ -39,7 +39,12 @@
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Types.UniqueType;
 import com.sun.tools.javac.file.BaseFileObject;
+import com.sun.tools.javac.jvm.Pool.DynamicMethod;
+import com.sun.tools.javac.jvm.Pool.Method;
+import com.sun.tools.javac.jvm.Pool.MethodHandle;
+import com.sun.tools.javac.jvm.Pool.Variable;
 import com.sun.tools.javac.util.*;
 
 import static com.sun.tools.javac.code.BoundKind.*;
@@ -142,7 +147,7 @@
     /** The bootstrap methods to be written in the corresponding class attribute
      *  (one for each invokedynamic)
      */
-    Map bootstrapMethods;
+    Map bootstrapMethods;
 
     /** The log to use for verbose output.
      */
@@ -477,10 +482,10 @@
         while (i < pool.pp) {
             Object value = pool.pool[i];
             Assert.checkNonNull(value);
-            if (value instanceof Pool.Method)
-                value = ((Pool.Method)value).m;
-            else if (value instanceof Pool.Variable)
-                value = ((Pool.Variable)value).v;
+            if (value instanceof Method)
+                value = ((Method)value).m;
+            else if (value instanceof Variable)
+                value = ((Variable)value).v;
 
             if (value instanceof MethodSymbol) {
                 MethodSymbol m = (MethodSymbol)value;
@@ -493,8 +498,9 @@
                 } else {
                     //invokedynamic
                     DynamicMethodSymbol dynSym = (DynamicMethodSymbol)m;
-                    Pool.MethodHandle handle = new Pool.MethodHandle(dynSym.bsmKind, dynSym.bsm);
-                    bootstrapMethods.put(dynSym, handle);
+                    MethodHandle handle = new MethodHandle(dynSym.bsmKind, dynSym.bsm, types);
+                    DynamicMethod dynMeth = new DynamicMethod(dynSym, types);
+                    bootstrapMethods.put(dynMeth, handle);
                     //init cp entries
                     pool.put(names.BootstrapMethods);
                     pool.put(handle);
@@ -531,7 +537,7 @@
                 NameAndType nt = (NameAndType)value;
                 poolbuf.appendByte(CONSTANT_NameandType);
                 poolbuf.appendChar(pool.put(nt.name));
-                poolbuf.appendChar(pool.put(typeSig(nt.type)));
+                poolbuf.appendChar(pool.put(typeSig(nt.uniqueType.type)));
             } else if (value instanceof Integer) {
                 poolbuf.appendByte(CONSTANT_Integer);
                 poolbuf.appendInt(((Integer)value).intValue());
@@ -549,17 +555,18 @@
             } else if (value instanceof String) {
                 poolbuf.appendByte(CONSTANT_String);
                 poolbuf.appendChar(pool.put(names.fromString((String)value)));
-            } else if (value instanceof MethodType) {
-                MethodType mtype = (MethodType)value;
-                poolbuf.appendByte(CONSTANT_MethodType);
-                poolbuf.appendChar(pool.put(typeSig(mtype)));
-            } else if (value instanceof Type) {
-                Type type = (Type)value;
-                if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
-                poolbuf.appendByte(CONSTANT_Class);
-                poolbuf.appendChar(pool.put(xClassName(type)));
-            } else if (value instanceof Pool.MethodHandle) {
-                Pool.MethodHandle ref = (Pool.MethodHandle)value;
+            } else if (value instanceof UniqueType) {
+                Type type = ((UniqueType)value).type;
+                if (type instanceof MethodType) {
+                    poolbuf.appendByte(CONSTANT_MethodType);
+                    poolbuf.appendChar(pool.put(typeSig((MethodType)type)));
+                } else {
+                    if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
+                    poolbuf.appendByte(CONSTANT_Class);
+                    poolbuf.appendChar(pool.put(xClassName(type)));
+                }
+            } else if (value instanceof MethodHandle) {
+                MethodHandle ref = (MethodHandle)value;
                 poolbuf.appendByte(CONSTANT_MethodHandle);
                 poolbuf.appendByte(ref.refKind);
                 poolbuf.appendChar(pool.put(ref.refSym));
@@ -589,7 +596,7 @@
         return new NameAndType(fieldName(sym),
                                retrofit
                                ? sym.erasure(types)
-                               : sym.externalType(types));
+                               : sym.externalType(types), types);
         // if we retrofit, then the NameAndType has been read in as is
         // and no change is necessary. If we compile normally, the
         // NameAndType is generated from a symbol reference, and the
@@ -714,7 +721,7 @@
             endAttr(alenIdx);
             acount++;
         }
-        acount += writeJavaAnnotations(sym.getAnnotationMirrors());
+        acount += writeJavaAnnotations(sym.getRawAttributes());
         return acount;
     }
 
@@ -725,7 +732,7 @@
         boolean hasVisible = false;
         boolean hasInvisible = false;
         if (m.params != null) for (VarSymbol s : m.params) {
-            for (Attribute.Compound a : s.getAnnotationMirrors()) {
+            for (Attribute.Compound a : s.getRawAttributes()) {
                 switch (types.getRetention(a)) {
                 case SOURCE: break;
                 case CLASS: hasInvisible = true; break;
@@ -741,7 +748,7 @@
             databuf.appendByte(m.params.length());
             for (VarSymbol s : m.params) {
                 ListBuffer buf = new ListBuffer();
-                for (Attribute.Compound a : s.getAnnotationMirrors())
+                for (Attribute.Compound a : s.getRawAttributes())
                     if (types.getRetention(a) == RetentionPolicy.RUNTIME)
                         buf.append(a);
                 databuf.appendChar(buf.length());
@@ -756,7 +763,7 @@
             databuf.appendByte(m.params.length());
             for (VarSymbol s : m.params) {
                 ListBuffer buf = new ListBuffer();
-                for (Attribute.Compound a : s.getAnnotationMirrors())
+                for (Attribute.Compound a : s.getRawAttributes())
                     if (types.getRetention(a) == RetentionPolicy.CLASS)
                         buf.append(a);
                 databuf.appendChar(buf.length());
@@ -951,14 +958,16 @@
     void writeBootstrapMethods() {
         int alenIdx = writeAttr(names.BootstrapMethods);
         databuf.appendChar(bootstrapMethods.size());
-        for (Map.Entry entry : bootstrapMethods.entrySet()) {
-            DynamicMethodSymbol dsym = (DynamicMethodSymbol)entry.getKey();
+        for (Map.Entry entry : bootstrapMethods.entrySet()) {
+            DynamicMethod dmeth = entry.getKey();
+            DynamicMethodSymbol dsym = (DynamicMethodSymbol)dmeth.baseSymbol();
             //write BSM handle
             databuf.appendChar(pool.get(entry.getValue()));
             //write static args length
             databuf.appendChar(dsym.staticArgs.length);
             //write static args array
-            for (Object o : dsym.staticArgs) {
+            Object[] uniqueArgs = dmeth.uniqueStaticArgs;
+            for (Object o : uniqueArgs) {
                 databuf.appendChar(pool.get(o));
             }
         }
@@ -1534,7 +1543,7 @@
         pool = c.pool;
         innerClasses = null;
         innerClassesQueue = null;
-        bootstrapMethods = new LinkedHashMap();
+        bootstrapMethods = new LinkedHashMap();
 
         Type supertype = types.supertype(c.type);
         List interfaces = types.interfaces(c.type);
@@ -1627,7 +1636,7 @@
         }
 
         acount += writeFlagAttrs(c.flags());
-        acount += writeJavaAnnotations(c.getAnnotationMirrors());
+        acount += writeJavaAnnotations(c.getRawAttributes());
         acount += writeEnclosingMethodAttribute(c);
         acount += writeExtraClassAttributes(c);
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/Code.java
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Dec 28 18:39:09 2012 -0800
@@ -27,6 +27,7 @@
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Types.UniqueType;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
@@ -901,6 +902,7 @@
         if (o instanceof ClassSymbol) return syms.classType;
         if (o instanceof Type.ArrayType) return syms.classType;
         if (o instanceof Type.MethodType) return syms.methodTypeType;
+        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
         if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
         throw new AssertionError(o);
     }
@@ -1030,7 +1032,7 @@
             Object o = pool.pool[od];
             Type t = (o instanceof Symbol)
                 ? ((Symbol)o).erasure(types)
-                : types.erasure(((Type)o));
+                : types.erasure((((UniqueType)o).type));
             state.push(t);
             break; }
         case ldc2w:
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/Gen.java
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Dec 28 18:39:09 2012 -0800
@@ -94,6 +94,10 @@
         return instance;
     }
 
+    /* Constant pool, reset by genClass.
+     */
+    private Pool pool;
+
     protected Gen(Context context) {
         context.put(genKey, this);
 
@@ -126,6 +130,7 @@
         genCrt = options.isSet(XJCOV);
         debugCode = options.isSet("debugcode");
         allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
+        pool = new Pool(types);
 
         generateIproxies =
             target.requiresIproxy() ||
@@ -174,10 +179,6 @@
      */
     private boolean useJsrLocally;
 
-    /* Constant pool, reset by genClass.
-     */
-    private Pool pool = new Pool();
-
     /** Code buffer, set by genMethod.
      */
     private Code code;
@@ -705,7 +706,7 @@
         }
         int startpc = code.curPc();
         genStat(tree, env);
-        if (tree.hasTag(BLOCK)) crtFlags |= CRT_BLOCK;
+        if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
         code.crt.put(tree, crtFlags, startpc, code.curPc());
     }
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/jvm/Pool.java
--- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri Dec 28 18:39:09 2012 -0800
@@ -28,6 +28,9 @@
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.code.Types.UniqueType;
 
 import com.sun.tools.javac.util.ArrayUtils;
 import com.sun.tools.javac.util.Assert;
@@ -60,11 +63,14 @@
      */
     Map indices;
 
+    Types types;
+
     /** Construct a pool with given number of elements and element array.
      */
-    public Pool(int pp, Object[] pool) {
+    public Pool(int pp, Object[] pool, Types types) {
         this.pp = pp;
         this.pool = pool;
+        this.types = types;
         this.indices = new HashMap(pool.length);
         for (int i = 1; i < pp; i++) {
             if (pool[i] != null) indices.put(pool[i], i);
@@ -73,8 +79,8 @@
 
     /** Construct an empty pool.
      */
-    public Pool() {
-        this(1, new Object[64]);
+    public Pool(Types types) {
+        this(1, new Object[64], types);
     }
 
     /** Return the number of entries in the constant pool.
@@ -114,11 +120,13 @@
 
     Object makePoolValue(Object o) {
         if (o instanceof DynamicMethodSymbol) {
-            return new DynamicMethod((DynamicMethodSymbol)o);
+            return new DynamicMethod((DynamicMethodSymbol)o, types);
         } else if (o instanceof MethodSymbol) {
-            return new Method((MethodSymbol)o);
+            return new Method((MethodSymbol)o, types);
         } else if (o instanceof VarSymbol) {
-            return new Variable((VarSymbol)o);
+            return new Variable((VarSymbol)o, types);
+        } else if (o instanceof Type) {
+            return new UniqueType((Type)o, types);
         } else {
             return o;
         }
@@ -134,9 +142,11 @@
 
     static class Method extends DelegatedSymbol {
         MethodSymbol m;
-        Method(MethodSymbol m) {
+        UniqueType uniqueType;
+        Method(MethodSymbol m, Types types) {
             super(m);
             this.m = m;
+            this.uniqueType = new UniqueType(m.type, types);
         }
         public boolean equals(Object other) {
             if (!(other instanceof Method)) return false;
@@ -144,20 +154,22 @@
             return
                 o.name == m.name &&
                 o.owner == m.owner &&
-                o.type.equals(m.type);
+                ((Method)other).uniqueType.equals(uniqueType);
         }
         public int hashCode() {
             return
                 m.name.hashCode() * 33 +
                 m.owner.hashCode() * 9 +
-                m.type.hashCode();
+                uniqueType.hashCode();
         }
     }
 
     static class DynamicMethod extends Method {
+        public Object[] uniqueStaticArgs;
 
-        DynamicMethod(DynamicMethodSymbol m) {
-            super(m);
+        DynamicMethod(DynamicMethodSymbol m, Types types) {
+            super(m, types);
+            uniqueStaticArgs = getUniqueTypeArray(m.staticArgs, types);
         }
 
         @Override
@@ -168,7 +180,8 @@
             DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)other).m;
             return dm1.bsm == dm2.bsm &&
                         dm1.bsmKind == dm2.bsmKind &&
-                        Arrays.equals(dm1.staticArgs, dm2.staticArgs);
+                        Arrays.equals(uniqueStaticArgs,
+                            ((DynamicMethod)other).uniqueStaticArgs);
         }
 
         @Override
@@ -178,17 +191,31 @@
             hash += dm.bsmKind * 7 +
                     dm.bsm.hashCode() * 11;
             for (int i = 0; i < dm.staticArgs.length; i++) {
-                hash += (dm.staticArgs[i].hashCode() * 23);
+                hash += (uniqueStaticArgs[i].hashCode() * 23);
             }
             return hash;
         }
+
+        private Object[] getUniqueTypeArray(Object[] objects, Types types) {
+            Object[] result = new Object[objects.length];
+            for (int i = 0; i < objects.length; i++) {
+                if (objects[i] instanceof Type) {
+                    result[i] = new UniqueType((Type)objects[i], types);
+                } else {
+                    result[i] = objects[i];
+                }
+            }
+            return result;
+        }
     }
 
     static class Variable extends DelegatedSymbol {
         VarSymbol v;
-        Variable(VarSymbol v) {
+        UniqueType uniqueType;
+        Variable(VarSymbol v, Types types) {
             super(v);
             this.v = v;
+            this.uniqueType = new UniqueType(v.type, types);
         }
         public boolean equals(Object other) {
             if (!(other instanceof Variable)) return false;
@@ -196,13 +223,13 @@
             return
                 o.name == v.name &&
                 o.owner == v.owner &&
-                o.type.equals(v.type);
+                ((Variable)other).uniqueType.equals(uniqueType);
         }
         public int hashCode() {
             return
                 v.name.hashCode() * 33 +
                 v.owner.hashCode() * 9 +
-                v.type.hashCode();
+                uniqueType.hashCode();
         }
     }
 
@@ -214,9 +241,12 @@
         /** Reference symbol */
         Symbol refSym;
 
-        public MethodHandle(int refKind, Symbol refSym) {
+        UniqueType uniqueType;
+
+        public MethodHandle(int refKind, Symbol refSym, Types types) {
             this.refKind = refKind;
             this.refSym = refSym;
+            this.uniqueType = new UniqueType(this.refSym.type, types);
             checkConsistent();
         }
         public boolean equals(Object other) {
@@ -227,14 +257,14 @@
             return
                 o.name == refSym.name &&
                 o.owner == refSym.owner &&
-                o.type.equals(refSym.type);
+                ((MethodHandle)other).uniqueType.equals(uniqueType);
         }
         public int hashCode() {
             return
                 refKind * 65 +
                 refSym.name.hashCode() * 33 +
                 refSym.owner.hashCode() * 9 +
-                refSym.type.hashCode();
+                uniqueType.hashCode();
         }
 
         /**
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Dec 28 18:39:09 2012 -0800
@@ -928,6 +928,16 @@
         }
     }
 
+    /**
+     * Set needRootClasses to true, in JavaCompiler subclass constructor
+     * that want to collect public apis of classes supplied on the command line.
+     */
+    protected boolean needRootClasses = false;
+
+    /**
+     * The list of classes explicitly supplied on the command line for compilation.
+     * Not always populated.
+     */
     private List rootClasses;
 
     /**
@@ -984,9 +994,10 @@
             }
         }
 
-        //If generating source, remember the classes declared in
-        //the original compilation units listed on the command line.
-        if (sourceOutput || stubOutput) {
+        // If generating source, or if tracking public apis,
+        // then remember the classes declared in
+        // the original compilation units listed on the command line.
+        if (needRootClasses || sourceOutput || stubOutput) {
             ListBuffer cdefs = lb();
             for (JCCompilationUnit unit : roots) {
                 for (List defs = unit.defs;
@@ -1247,6 +1258,12 @@
                 attr.postAttr(env.tree);
             }
             compileStates.put(env, CompileState.ATTR);
+            if (rootClasses != null && rootClasses.contains(env.enclClass)) {
+                // This was a class that was explicitly supplied for compilation.
+                // If we want to capture the public api of this class,
+                // then now is a good time to do it.
+                reportPublicApi(env.enclClass.sym);
+            }
         }
         finally {
             log.useSource(prev);
@@ -1255,6 +1272,14 @@
         return env;
     }
 
+    /** Report the public api of a class that was supplied explicitly for compilation,
+     *  for example on the command line to javac.
+     * @param sym The symbol of the class.
+     */
+    public void reportPublicApi(ClassSymbol sym) {
+       // Override to collect the reported public api.
+    }
+
     /**
      * Perform dataflow checks on attributed parse trees.
      * These include checks for definite assignment and unreachable statements.
@@ -1675,7 +1700,7 @@
 
     /** Print numbers of errors and warnings.
      */
-    protected void printCount(String kind, int count) {
+    public void printCount(String kind, int count) {
         if (count != 0) {
             String key;
             if (count == 1)
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/main/Main.java
--- a/src/share/classes/com/sun/tools/javac/main/Main.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/main/Main.java	Fri Dec 28 18:39:09 2012 -0800
@@ -44,6 +44,8 @@
 
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.Plugin;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.api.BasicJavacTask;
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.file.CacheFSInfo;
 import com.sun.tools.javac.file.JavacFileManager;
@@ -428,6 +430,7 @@
             if (batchMode)
                 CacheFSInfo.preRegister(context);
 
+            // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
             // invoke any available plugins
             String plugins = options.get(PLUGIN);
             if (plugins != null) {
@@ -448,7 +451,7 @@
                             try {
                                 if (task == null)
                                     task = JavacTask.instance(pEnv);
-                                plugin.call(task, p.tail.toArray(new String[p.tail.size()]));
+                                plugin.init(task, p.tail.toArray(new String[p.tail.size()]));
                             } catch (Throwable ex) {
                                 if (apiMode)
                                     throw new RuntimeException(ex);
@@ -464,11 +467,32 @@
                 }
             }
 
+            comp = JavaCompiler.instance(context);
+
+            // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
+            String xdoclint = options.get(XDOCLINT);
+            String xdoclintCustom = options.get(XDOCLINT_CUSTOM);
+            if (xdoclint != null || xdoclintCustom != null) {
+                Set doclintOpts = new LinkedHashSet();
+                if (xdoclint != null)
+                    doclintOpts.add(DocLint.XMSGS_OPTION);
+                if (xdoclintCustom != null) {
+                    for (String s: xdoclintCustom.split("\\s+")) {
+                        if (s.isEmpty())
+                            continue;
+                        doclintOpts.add(s.replace(XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
+                    }
+                }
+                if (!(doclintOpts.size() == 1
+                        && doclintOpts.iterator().next().equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) {
+                    JavacTask t = BasicJavacTask.instance(context);
+                    new DocLint().init(t, doclintOpts.toArray(new String[doclintOpts.size()]));
+                    comp.keepComments = true;
+                }
+            }
+
             fileManager = context.get(JavaFileManager.class);
 
-            comp = JavaCompiler.instance(context);
-            if (comp == null) return Result.SYSERR;
-
             if (!files.isEmpty()) {
                 // add filenames to fileObjects
                 comp = JavaCompiler.instance(context);
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/main/Option.java
--- a/src/share/classes/com/sun/tools/javac/main/Option.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/main/Option.java	Fri Dec 28 18:39:09 2012 -0800
@@ -25,28 +25,30 @@
 
 package com.sun.tools.javac.main;
 
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
 import java.util.Collections;
-import com.sun.tools.javac.util.Log.PrefixKind;
-import com.sun.tools.javac.util.Log.WriterKind;
-import com.sun.tools.javac.util.Log;
+import java.util.EnumSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import com.sun.tools.doclint.DocLint;
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.PrefixKind;
+import com.sun.tools.javac.util.Log.WriterKind;
 import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.util.EnumSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import javax.lang.model.SourceVersion;
-
 import static com.sun.tools.javac.main.Option.ChoiceKind.*;
+import static com.sun.tools.javac.main.Option.OptionGroup.*;
 import static com.sun.tools.javac.main.Option.OptionKind.*;
-import static com.sun.tools.javac.main.Option.OptionGroup.*;
 
 /**
  * Options for javac. The specific Option to handle a command-line option
@@ -79,6 +81,24 @@
     XLINT_CUSTOM("-Xlint:", "opt.Xlint.suboptlist",
             EXTENDED,   BASIC, ANYOF, getXLintChoices()),
 
+    XDOCLINT("-Xdoclint", "opt.Xdoclint", EXTENDED, BASIC),
+
+    XDOCLINT_CUSTOM("-Xdoclint:", "opt.Xdoclint.subopts", "opt.Xdoclint.custom", EXTENDED, BASIC) {
+        @Override
+        public boolean matches(String option) {
+            return DocLint.isValidOption(
+                    option.replace(XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
+        }
+
+        @Override
+        public boolean process(OptionHelper helper, String option) {
+            String prev = helper.get(XDOCLINT_CUSTOM);
+            String next = (prev == null) ? option : (prev + " " + option);
+            helper.put(XDOCLINT_CUSTOM.text, next);
+            return false;
+        }
+    },
+
     // -nowarn is retained for command-line backward compatibility
     NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
         @Override
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/model/JavacTypes.java
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Fri Dec 28 18:39:09 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,16 @@
 
 package com.sun.tools.javac.model;
 
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.EnumSet;
+
 import javax.lang.model.element.*;
 import javax.lang.model.type.*;
+
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.util.*;
@@ -301,4 +306,31 @@
             throw new IllegalArgumentException(o.toString());
         return clazz.cast(o);
     }
+
+    public Set getOverriddenMethods(Element elem) {
+        if (elem.getKind() != ElementKind.METHOD
+                || elem.getModifiers().contains(Modifier.STATIC)
+                || elem.getModifiers().contains(Modifier.PRIVATE))
+            return Collections.emptySet();
+
+        if (!(elem instanceof MethodSymbol))
+            throw new IllegalArgumentException();
+
+        MethodSymbol m = (MethodSymbol) elem;
+        ClassSymbol origin = (ClassSymbol) m.owner;
+
+        Set results = new LinkedHashSet();
+        for (Type t : types.closure(origin.type)) {
+            if (t != origin.type) {
+                ClassSymbol c = (ClassSymbol) t.tsym;
+                for (Scope.Entry e = c.members().lookup(m.name); e.scope != null; e = e.next()) {
+                    if (e.sym.kind == Kinds.MTH && m.overrides(e.sym, origin, types, true)) {
+                        results.add((MethodSymbol) e.sym);
+                    }
+                }
+            }
+        }
+
+        return results;
+    }
 }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
--- a/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Fri Dec 28 18:39:09 2012 -0800
@@ -25,15 +25,12 @@
 
 package com.sun.tools.javac.parser;
 
-import com.sun.tools.javac.util.Filter;
 import java.text.BreakIterator;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
 
 import com.sun.source.doctree.AttributeTree.ValueKind;
@@ -52,7 +49,6 @@
 import com.sun.tools.javac.tree.DocTreeMaker;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.DiagnosticSource;
-import com.sun.tools.javac.util.JCDiagnostic;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
@@ -736,7 +732,9 @@
             nextChar();
             return m.at(p).Entity(names.fromChars(buf, namep, bp - namep - 1));
         } else {
-            String code = checkSemi ? "dc.missing.semicolon" : "dc.bad.entity";
+            String code = checkSemi
+                    ? "dc.missing.semicolon"
+                    : "dc.bad.entity";
             return erroneous(code, p);
         }
     }
@@ -888,8 +886,10 @@
     }
 
     protected void addPendingText(ListBuffer list, int textEnd) {
-        if (textStart != -1 && textStart <= textEnd) {
-            list.add(m.at(textStart).Text(newString(textStart, textEnd + 1)));
+        if (textStart != -1) {
+            if (textStart <= textEnd) {
+                list.add(m.at(textStart).Text(newString(textStart, textEnd + 1)));
+            }
             textStart = -1;
         }
     }
@@ -1196,6 +1196,16 @@
                                 return m.at(pos).See(html);
                             break;
 
+                        case '@':
+                            if (newline)
+                                throw new ParseException("dc.no.content");
+                            break;
+
+                        case EOI:
+                            if (bp == buf.length - 1)
+                                throw new ParseException("dc.no.content");
+                            break;
+
                         default:
                             if (isJavaIdentifierStart(ch) || ch == '#') {
                                 DCReference ref = reference(true);
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/resources/compiler.properties
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Dec 28 18:39:09 2012 -0800
@@ -2364,6 +2364,9 @@
 compiler.err.dc.missing.semicolon=\
     semicolon missing
 
+compiler.err.dc.no.content=\
+    no content
+
 compiler.err.dc.no.tag.name=\
     no tag name after '@'
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/resources/javac.properties
--- a/src/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/resources/javac.properties	Fri Dec 28 18:39:09 2012 -0800
@@ -138,6 +138,14 @@
     Enable recommended warnings
 javac.opt.Xlint.suboptlist=\
     Enable or disable specific warnings
+javac.opt.Xdoclint=\
+    Enable recommended checks for problems in javadoc comments
+javac.opt.Xdoclint.subopts = \
+    (all|[-])[/]
+javac.opt.Xdoclint.custom=\n\
+\        Enable or disable specific checks for problems in javadoc comments,\n\
+\        where  is one of accessibility, html, reference, or syntax,\n\
+\        and  is one of public, protected, package, or private.
 javac.opt.Xstdout=\
     Redirect standard output
 javac.opt.X=\
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
--- a/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Fri Dec 28 18:39:09 2012 -0800
@@ -33,6 +33,7 @@
 import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.jvm.ClassWriter;
 import com.sun.tools.javac.jvm.Pool;
@@ -173,7 +174,8 @@
                                    List.>nil());
 
         Type.moreInfo = true;
-        Pool pool = new Pool();
+        Types types = Types.instance(task.getContext());
+        Pool pool = new Pool(types);
         for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
             String className = fm.inferBinaryName(jarLocation, file);
             int index = className.lastIndexOf('.');
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/tree/DCTree.java
--- a/src/share/classes/com/sun/tools/javac/tree/DCTree.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/DCTree.java	Fri Dec 28 18:39:09 2012 -0800
@@ -36,6 +36,8 @@
 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Name;
+import java.io.IOException;
+import java.io.StringWriter;
 import javax.tools.JavaFileObject;
 
 /**
@@ -65,6 +67,21 @@
         return new SimpleDiagnosticPosition(dc.comment.getSourcePos(pos));
     }
 
+    /** Convert a tree to a pretty-printed string. */
+    @Override
+    public String toString() {
+        StringWriter s = new StringWriter();
+        try {
+            new DocPretty(s).print(this);
+        }
+        catch (IOException e) {
+            // should never happen, because StringWriter is defined
+            // never to throw any IOExceptions
+            throw new AssertionError(e);
+        }
+        return s.toString();
+    }
+
     public static class DCDocComment extends DCTree implements DocCommentTree {
         final Comment comment; // required for the implicit source pos table
 
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/tree/DocPretty.java
--- a/src/share/classes/com/sun/tools/javac/tree/DocPretty.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/DocPretty.java	Fri Dec 28 18:39:09 2012 -0800
@@ -81,7 +81,7 @@
     /**
      * Print list.
      */
-    protected void print(List list) throws IOException {
+    public void print(List list) throws IOException {
         for (DocTree t: list) {
             print(t);
         }
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Dec 28 18:39:09 2012 -0800
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.tree;
 
 
+
 import com.sun.source.tree.Tree;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.comp.AttrContext;
@@ -330,6 +331,13 @@
         return (docComments == null) ? null : docComments.getCommentText(tree);
     }
 
+    public static DCTree.DCDocComment getCommentTree(Env env, JCTree tree) {
+        DocCommentTable docComments = (tree.hasTag(JCTree.Tag.TOPLEVEL))
+                ? ((JCCompilationUnit) tree).docComments
+                : env.toplevel.docComments;
+        return (docComments == null) ? null : docComments.getCommentTree(tree);
+    }
+
     /** The position of the first statement in a block, or the position of
      *  the block itself if it is empty.
      */
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Fri Dec 28 18:39:09 2012 -0800
@@ -684,7 +684,7 @@
     public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
         return (JCVariableDecl)
             new JCVariableDecl(
-                Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),
+                Modifiers(v.flags(), Annotations(v.getRawAttributes())),
                 v.name,
                 Type(v.type),
                 init,
@@ -800,7 +800,7 @@
     public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
         return (JCMethodDecl)
             new JCMethodDecl(
-                Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
+                Modifiers(m.flags(), Annotations(m.getRawAttributes())),
                 m.name,
                 Type(mtype.getReturnType()),
                 TypeParams(mtype.getTypeArguments()),
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java
--- a/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -276,6 +276,10 @@
         return false;
     }
 
+    public boolean isFunctionalInterface() {
+        return env.types.isFunctionalInterface(tsym);
+    }
+
     /**
      * Return the package that this class is contained in.
      */
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java
--- a/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -76,6 +76,13 @@
     }
 
     /**
+     * Return true if this method is default
+     */
+    public boolean isDefault() {
+        return (sym.flags() & Flags.DEFAULT) != 0;
+    }
+
+    /**
      * Return true if this method is abstract
      */
     public boolean isAbstract() {
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java
--- a/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -288,9 +288,9 @@
      * Return an empty array if there are none.
      */
     public AnnotationDesc[] annotations() {
-        AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
+        AnnotationDesc res[] = new AnnotationDesc[sym.getRawAttributes().length()];
         int i = 0;
-        for (Attribute.Compound a : sym.getAnnotationMirrors()) {
+        for (Attribute.Compound a : sym.getRawAttributes()) {
             res[i++] = new AnnotationDescImpl(env, a);
         }
         return res;
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javadoc/ParameterImpl.java
--- a/src/share/classes/com/sun/tools/javadoc/ParameterImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javadoc/ParameterImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -99,9 +99,9 @@
      * Return an empty array if there are none.
      */
     public AnnotationDesc[] annotations() {
-        AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
+        AnnotationDesc res[] = new AnnotationDesc[sym.getRawAttributes().length()];
         int i = 0;
-        for (Attribute.Compound a : sym.getAnnotationMirrors()) {
+        for (Attribute.Compound a : sym.getRawAttributes()) {
             res[i++] = new AnnotationDescImpl(env, a);
         }
         return res;
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java
--- a/src/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java	Fri Dec 28 18:39:09 2012 -0800
@@ -164,9 +164,9 @@
      * Return an empty array if there are none.
      */
     public AnnotationDesc[] annotations() {
-        AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
+        AnnotationDesc res[] = new AnnotationDesc[sym.getRawAttributes().length()];
         int i = 0;
-        for (Attribute.Compound a : sym.getAnnotationMirrors()) {
+        for (Attribute.Compound a : sym.getRawAttributes()) {
             res[i++] = new AnnotationDescImpl(env, a);
         }
         return res;
diff -r 7d5032c2d747 -r 467e4d9281bc src/share/classes/javax/lang/model/element/ExecutableElement.java
--- a/src/share/classes/javax/lang/model/element/ExecutableElement.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/src/share/classes/javax/lang/model/element/ExecutableElement.java	Fri Dec 28 18:39:09 2012 -0800
@@ -78,6 +78,16 @@
     boolean isVarArgs();
 
     /**
+     * Returns {@code true} if this method is a default method and
+     * returns {@code false} otherwise.
+     *
+     * @return {@code true} if this method is a default method and
+     * {@code false} otherwise
+     * @since 1.8
+     */
+    boolean isDefault();
+
+    /**
      * Returns the exceptions and other throwables listed in this
      * method or constructor's {@code throws} clause in declaration
      * order.
diff -r 7d5032c2d747 -r 467e4d9281bc test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java
--- a/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java	Thu Dec 27 12:15:17 2012 -0800
+++ b/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java	Fri Dec 28 18:39:09 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -207,7 +207,7 @@
             "Instance Methods " +
             "" +
             "Concrete Methods " +
-            "" +
+            "" +
             "Deprecated Methods " +
             ""
         },
diff -r 7d5032c2d747 -r 467e4d9281bc test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java	Fri Dec 28 18:39:09 2012 -0800
@@ -0,0 +1,102 @@
+/*
+ * 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      8004893
+ * @summary  Make sure that the lambda feature changes work fine in
+ *           javadoc.
+ * @author   bpatel
+ * @library  ../lib/
+ * @build    JavadocTester TestLambdaFeature
+ * @run main TestLambdaFeature
+ */
+
+public class TestLambdaFeature extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8004893";
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        {BUG_ID + FS + "pkg" + FS + "A.html",
+            "default void"},
+        {BUG_ID + FS + "pkg" + FS + "A.html",
+            "
default void defaultMethod()
"}, + {BUG_ID + FS + "pkg" + FS + "A.html", + "" + + "All Methods " + + "" + + "Instance Methods" + + " " + + "Abstract Methods " + + "" + + "Default Methods" + + " "}, + {BUG_ID + FS + "pkg" + FS + "A.html", + "
" + NL + "
Functional Interface:
" + NL + + "
This is a functional interface and can therefore be used as " + + "the assignment target for a lambda expression or method " + + "reference.
" + NL + "
"} + }; + private static final String[][] NEGATED_TEST = { + {BUG_ID + FS + "pkg" + FS + "A.html", + "default default void"}, + {BUG_ID + FS + "pkg" + FS + "A.html", + "
default default void defaultMethod()
"}, + {BUG_ID + FS + "pkg" + FS + "B.html", + "default void"}, + {BUG_ID + FS + "pkg" + FS + "B.html", + "
" + NL + "
Functional Interface:
"} + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestLambdaFeature tester = new TestLambdaFeature(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/com/sun/javadoc/testLambdaFeature/pkg/A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/javadoc/testLambdaFeature/pkg/A.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public interface A { + + public void method1(); + + public default void defaultMethod() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/com/sun/javadoc/testLambdaFeature/pkg/B.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/javadoc/testLambdaFeature/pkg/B.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public abstract class B { + + public abstract void method1(); + + public void method2() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java --- a/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java Thu Dec 27 12:15:17 2012 -0800 +++ b/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java Fri Dec 28 18:39:09 2012 -0800 @@ -55,7 +55,7 @@ "Instance Methods " + "" + "Concrete Methods " + - "" + + "" + "Deprecated Methods " + "" }, @@ -87,7 +87,7 @@ "Abstract Methods " + "" + "Concrete Methods " + - "" + + "" + "Deprecated Methods " + "" }, diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,65 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -ref AccessTest.protected.out AccessTest.java + * @run main DocLintTester -Xmsgs -ref AccessTest.private.out AccessTest.java + * @run main DocLintTester -Xmsgs:syntax -ref AccessTest.private.out AccessTest.java + * @run main DocLintTester -Xmsgs:syntax/public -ref AccessTest.public.out AccessTest.java + * @run main DocLintTester -Xmsgs:syntax/protected -ref AccessTest.protected.out AccessTest.java + * @run main DocLintTester -Xmsgs:syntax/package -ref AccessTest.package.out AccessTest.java + * @run main DocLintTester -Xmsgs:syntax/private -ref AccessTest.private.out AccessTest.java + * @run main DocLintTester -Xmsgs:all,-syntax AccessTest.java + * @run main DocLintTester -Xmsgs:all,-syntax/public AccessTest.java + * @run main DocLintTester -Xmsgs:all,-syntax/protected -ref AccessTest.public.out AccessTest.java + * @run main DocLintTester -Xmsgs:all,-syntax/package -ref AccessTest.protected.out AccessTest.java + * @run main DocLintTester -Xmsgs:all,-syntax/private -ref AccessTest.package.out AccessTest.java + */ + +/** */ +public class AccessTest { + /** + * public a < b + */ + public void public_syntax_error() { } + + /** + * protected a < b + */ + protected void protected_syntax_error() { } + + /** + * package-private a < b + */ + void syntax_error() { } + + /** + * private a < b + */ + private void private_syntax_error() { } +} + +/** */ +class AccessTest2 { + /** + * public a < b + */ + public void public_syntax_error() { } + + /** + * protected a < b + */ + protected void protected_syntax_error() { } + + /** + * package-private a < b + */ + void syntax_error() { } + + /** + * private a < b + */ + private void private_syntax_error() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessTest.package.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessTest.package.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,20 @@ +AccessTest.java:23: error: malformed HTML + * public a < b + ^ +AccessTest.java:28: error: malformed HTML + * protected a < b + ^ +AccessTest.java:33: error: malformed HTML + * package-private a < b + ^ +AccessTest.java:46: error: malformed HTML + * public a < b + ^ +AccessTest.java:51: error: malformed HTML + * protected a < b + ^ +AccessTest.java:56: error: malformed HTML + * package-private a < b + ^ +6 errors + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessTest.private.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessTest.private.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,27 @@ +AccessTest.java:23: error: malformed HTML + * public a < b + ^ +AccessTest.java:28: error: malformed HTML + * protected a < b + ^ +AccessTest.java:33: error: malformed HTML + * package-private a < b + ^ +AccessTest.java:38: error: malformed HTML + * private a < b + ^ +AccessTest.java:46: error: malformed HTML + * public a < b + ^ +AccessTest.java:51: error: malformed HTML + * protected a < b + ^ +AccessTest.java:56: error: malformed HTML + * package-private a < b + ^ +AccessTest.java:61: error: malformed HTML + * private a < b + ^ +8 errors + + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessTest.protected.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessTest.protected.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,8 @@ +AccessTest.java:23: error: malformed HTML + * public a < b + ^ +AccessTest.java:28: error: malformed HTML + * protected a < b + ^ +2 errors + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessTest.public.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessTest.public.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +AccessTest.java:23: error: malformed HTML + * public a < b + ^ +1 error + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessibilityTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessibilityTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,44 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-accessibility AccessibilityTest.java + * @run main DocLintTester -ref AccessibilityTest.out AccessibilityTest.java + */ + +/** */ +public class AccessibilityTest { + + /** + *

...

+ */ + public void missing_h1() { } + + /** + *

...

+ *

...

+ */ + public void missing_h2() { } + + /** + * + */ + public void missing_alt() { } + + /** + *
head
data
+ */ + public void table_with_summary() { } + + /** + *
ok
head
data
+ */ + public void table_with_caption() { } + + /** + *
head
data
+ */ + public void table_without_summary_and_caption() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/AccessibilityTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/AccessibilityTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,13 @@ +AccessibilityTest.java:14: error: header used out of sequence:

+ *

...

+ ^ +AccessibilityTest.java:20: error: header used out of sequence:

+ *

...

+ ^ +AccessibilityTest.java:25: error: no "alt" attribute for image + * + ^ +AccessibilityTest.java:40: error: no summary or caption for table + *
head
data
+ ^ +4 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/DocLintTester.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/DocLintTester.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import com.sun.tools.doclint.DocLint; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.StringWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class DocLintTester { + + public static void main(String... args) throws Exception { + new DocLintTester().run(args); + } + + public void run(String... args) throws Exception { + String testSrc = System.getProperty("test.src"); + + File refFile = null; + List opts = new ArrayList(); + List files = new ArrayList(); + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (arg.equals("-ref")) { + refFile = new File(testSrc, args[++i]); + } else if (arg.startsWith("-Xmsgs")) { + opts.add(arg); + } else + files.add(new File(testSrc, arg)); + } + + check(opts, files, refFile); + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void check(List opts, List files, File refFile) throws Exception { + List args = new ArrayList(); + args.addAll(opts); + for (File file: files) + args.add(file.getPath()); + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + new DocLint().run(pw, args.toArray(new String[args.size()])); + pw.flush(); + String out = normalizeNewlines(removeFileNames(sw.toString())).trim(); + if (out != null) + System.err.println("Output:\n" + out); + + if (refFile == null) { + if (!out.isEmpty()) + error("unexpected output"); + } else { + String expect = readFile(refFile); + if (!expect.equals(out)) { + error("expected output not found"); + System.err.println("EXPECT>>" + expect + "<<"); + System.err.println(" FOUND>>" + out + "<<"); + } + } + } + + String readFile(File file) throws IOException { + StringBuilder sb = new StringBuilder(); + Reader in = new BufferedReader(new FileReader(file)); + try { + char[] buf = new char[1024]; + int n; + while ((n = in.read(buf)) != -1) + sb.append(buf, 0, n); + } finally { + in.close(); + } + return sb.toString().trim(); + } + + private static final Pattern dirFileLine = Pattern.compile( + "(?m)" // multi-line mode + + "^([^: ]+?)" // directory part of file name + + "([A-Za-z0-9.]+:[0-9]+:)"); // file name and line number + + String removeFileNames(String s) { + Matcher m = dirFileLine.matcher(s); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + m.appendReplacement(sb, "$2"); + } + m.appendTail(sb); + return sb.toString(); + } + + private static final String nl = System.getProperty("line.separator"); + String normalizeNewlines(String s) { + return (nl.equals("\n") ? s : s.replace(nl, "\n")); + } + + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyAuthorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyAuthorTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptyAuthorTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptyAuthorTest.out EmptyAuthorTest.java + */ + +/** @author */ +public class EmptyAuthorTest { +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyAuthorTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyAuthorTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptyAuthorTest.java:10: warning: no description for @author +/** @author */ + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyExceptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyExceptionTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptyExceptionTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptyExceptionTest.out EmptyExceptionTest.java + */ + +/** . */ +public class EmptyExceptionTest { + /** @exception NullPointerException */ + int emptyException() throws NullPointerException { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyExceptionTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyExceptionTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +EmptyExceptionTest.java:12: warning: no description for @exception + /** @exception NullPointerException */ + ^ +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyParamTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyParamTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptyParamTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptyParamTest.out EmptyParamTest.java + */ + +/** . */ +public class EmptyParamTest { + /** @param i */ + int emptyParam(int i) { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyParamTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyParamTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptyParamTest.java:12: warning: no description for @param + /** @param i */ + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyReturnTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyReturnTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptyReturnTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptyReturnTest.out EmptyReturnTest.java + */ + +/** . */ +public class EmptyReturnTest { + /** @return */ + int emptyReturn() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyReturnTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyReturnTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptyReturnTest.java:12: warning: no description for @return + /** @return */ + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySerialDataTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySerialDataTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptySerialDataTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptySerialDataTest.out EmptySerialDataTest.java + */ + +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** . */ +public class EmptySerialDataTest implements Serializable { + /** @serialData */ + private void writeObject(ObjectOutputStream s) { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySerialDataTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySerialDataTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptySerialDataTest.java:15: warning: no description for @serialData + /** @serialData */ + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySerialFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySerialFieldTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,22 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptySerialFieldTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptySerialFieldTest.out EmptySerialFieldTest.java + */ + +import java.io.ObjectStreamField; +import java.io.Serializable; + +/** . */ +public class EmptySerialFieldTest implements Serializable { + + /** + * @serialField empty String + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("empty", String.class), + }; +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySerialFieldTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySerialFieldTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptySerialFieldTest.java:17: warning: no description for @serialField + * @serialField empty String + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySinceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySinceTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptySinceTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptySinceTest.out EmptySinceTest.java + */ + +/** . */ +public class EmptySinceTest { + /** @since */ + int emptySince() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptySinceTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptySinceTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +EmptySinceTest.java:12: warning: no description for @since + /** @since */ + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyVersionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyVersionTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax EmptyVersionTest.java + * @run main DocLintTester -Xmsgs:syntax -ref EmptyVersionTest.out EmptyVersionTest.java + */ + +/** . */ +public class EmptyVersionTest { + /** @version */ + int missingVersion() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/EmptyVersionTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/EmptyVersionTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +EmptyVersionTest.java:12: warning: no description for @version + /** @version */ + ^ +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/HtmlAttrsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/HtmlAttrsTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-html HtmlAttrsTest.java + * @run main DocLintTester -ref HtmlAttrsTest.out HtmlAttrsTest.java + */ + +/** */ +public class HtmlAttrsTest { + /** + *

+ */ + public void unknown() { } + + /** + * alt + */ + public void obsolete() { } + + /** + * text + */ + public void obsolete_use_css() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/HtmlAttrsTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/HtmlAttrsTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,12 @@ +HtmlAttrsTest.java:13: error: unknown attribute: xyz + *

+ ^ +HtmlAttrsTest.java:18: warning: attribute obsolete: name + * alt + ^ +HtmlAttrsTest.java:23: warning: attribute obsolete, use CSS instead: size + * text + ^ +1 error +2 warnings + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/HtmlTagsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/HtmlTagsTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,58 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-html HtmlTagsTest.java + * @run main DocLintTester -ref HtmlTagsTest.out HtmlTagsTest.java + */ + +/** */ +public class HtmlTagsTest { + /** + * ... + */ + public void unknownTag1() { } + + /** + *

+ */ + public void unknownTag2() { } + + /** + *
+ */ + public void selfClosingTag() { } + + /** + * + */ + public void not_allowed() { } + + /** + *

+ */ + public void not_allowed_inline() { } + + /** + * {@link java.lang.String

} + * {@link java.lang.String

} + */ + public void not_allowed_inline_2() { } + + /** + * alt + */ + public void end_not_allowed() { } + + /** + * + */ + public void start_not_matched() { } + + /** + * + */ + public void end_unexpected() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/HtmlTagsTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/HtmlTagsTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,38 @@ +HtmlTagsTest.java:13: error: unknown tag: xyz + * ... + ^ +HtmlTagsTest.java:13: error: unknown tag: xyz + * ... + ^ +HtmlTagsTest.java:18: error: unknown tag: xyz + *

+ ^ +HtmlTagsTest.java:23: error: self-closing element not allowed + *
+ ^ +HtmlTagsTest.java:28: error: element not allowed in documentation comments: + * + ^ +HtmlTagsTest.java:33: error: block element not allowed within inline element : p + *

+ ^ +HtmlTagsTest.java:38: error: block element not allowed within @link: p + * {@link java.lang.String

} + ^ +HtmlTagsTest.java:39: error: block element not allowed within @link: p + * {@link java.lang.String

} + ^ +HtmlTagsTest.java:44: error: invalid end tag: + * alt + ^ +HtmlTagsTest.java:49: error: end tag missing: + * + ^ +HtmlTagsTest.java:54: error: unexpected end tag: + * + ^ +HtmlTagsTest.java:54: warning: empty tag + * + ^ +11 errors +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingCommentTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingCommentTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-missing MissingCommentTest.java + * @run main DocLintTester -Xmsgs:missing -ref MissingCommentTest.out MissingCommentTest.java + */ + +public class MissingCommentTest { + MissingCommentTest() { } + + int missingComment; + + void missingComment() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingCommentTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingCommentTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +MissingCommentTest.java:8: warning: no comment +public class MissingCommentTest { + ^ +MissingCommentTest.java:9: warning: no comment + MissingCommentTest() { } + ^ +MissingCommentTest.java:11: warning: no comment + int missingComment; + ^ +MissingCommentTest.java:13: warning: no comment + void missingComment() { } + ^ +4 warnings + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingParamsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingParamsTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,23 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-missing MissingParamsTest.java + * @run main DocLintTester -Xmsgs:missing -ref MissingParamsTest.out MissingParamsTest.java + */ + +/** . */ +public class MissingParamsTest { + /** */ + MissingParamsTest(int param) { } + + /** */ + MissingParamsTest() { } + + /** */ + void missingParam(int param) { } + + /** */ + void missingTyparam() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingParamsTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingParamsTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +MissingParamsTest.java:13: warning: no @param for param + MissingParamsTest(int param) { } + ^ +MissingParamsTest.java:16: warning: no @param for + MissingParamsTest() { } + ^ +MissingParamsTest.java:19: warning: no @param for param + void missingParam(int param) { } + ^ +MissingParamsTest.java:22: warning: no @param for + void missingTyparam() { } + ^ +4 warnings + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingReturnTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingReturnTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,23 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-missing MissingReturnTest.java + * @run main DocLintTester -Xmsgs:missing -ref MissingReturnTest.out MissingReturnTest.java + */ + +/** . */ +public class MissingReturnTest { + /** no return allowed */ + MissingReturnTest() { } + + /** no return allowed */ + void return_void() { } + + /** no return required */ + Void return_Void() { } + + /** */ + int missingReturn() { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingReturnTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingReturnTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +MissingReturnTest.java:22: warning: no @return + int missingReturn() { } + ^ +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingThrowsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingThrowsTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-missing MissingThrowsTest.java + * @run main DocLintTester -Xmsgs:missing -ref MissingThrowsTest.out MissingThrowsTest.java + */ + +/** */ +public class MissingThrowsTest { + /** */ + void missingThrows() throws Exception { } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/MissingThrowsTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/MissingThrowsTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +MissingThrowsTest.java:13: warning: no @throws for java.lang.Exception + void missingThrows() throws Exception { } + ^ +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/OptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/OptionTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,96 @@ +/* + * 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 8004832 + * @summary Add new doclint package + */ + +import com.sun.tools.doclint.DocLint; + +public class OptionTest { + public static void main(String... args) throws Exception { + new OptionTest().run(); + } + + String[] positiveTests = { + "-Xmsgs", + "-Xmsgs:all", + "-Xmsgs:none", + "-Xmsgs:accessibility", + "-Xmsgs:html", + "-Xmsgs:missing", + "-Xmsgs:reference", + "-Xmsgs:syntax", + "-Xmsgs:html/public", + "-Xmsgs:html/protected", + "-Xmsgs:html/package", + "-Xmsgs:html/private", + "-Xmsgs:-html/public", + "-Xmsgs:-html/protected", + "-Xmsgs:-html/package", + "-Xmsgs:-html/private", + "-Xmsgs:html,syntax", + "-Xmsgs:html,-syntax", + "-Xmsgs:-html,syntax", + "-Xmsgs:-html,-syntax", + "-Xmsgs:html/public,syntax", + "-Xmsgs:html,syntax/public", + "-Xmsgs:-html/public,syntax/public" + }; + + String[] negativeTests = { + "-typo", + "-Xmsgs:-all", + "-Xmsgs:-none", + "-Xmsgs:typo", + "-Xmsgs:html/typo", + "-Xmsgs:html/public,typo", + "-Xmsgs:html/public,syntax/typo", + }; + + void run() throws Exception { + test(positiveTests, true); + test(negativeTests, false); + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void test(String[] tests, boolean expect) { + for (String test: tests) { + System.err.println("test: " + test); + boolean found = DocLint.isValidOption(test); + if (found != expect) + error("Unexpected result: " + found + ",expected: " + expect); + } + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/OverridesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/OverridesTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,93 @@ +/* + * 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 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:all OverridesTest.java + */ + +/* + * This is a test that missing comments on methods may be inherited + * from overridden methods. As such, there should be no errors due + * to missing comments (or any other types of error) in this test. + */ + +/** An interface. */ +interface I1 { + /** + * A method + * @param p a param + * @throws Exception an exception + * @return an int + */ + int m(int p) throws Exception; +} + +/** An extending interface. */ +interface I2 extends I1 { } + +/** An abstract class. */ +abstract class C1 { + /** + * A method + * @param p a param + * @throws Exception an exception + * @return an int + */ + int m(int p) throws Exception; +} + +/** An implementing class. */ +class C2 implements I1 { + int m(int p) throws Exception { return p; } +} + +/** An extending class. */ +class C3 extends C1 { + int m(int p) throws Exception { return p; } +} + +/** An extending and implementing class. */ +class C4 extends C1 implements I1 { + int m(int p) throws Exception { return p; } +} + +/** An implementing class using inheritdoc. */ +class C5 implements I1 { + /** {@inheritDoc} */ + int m(int p) throws Exception { return p; } +} + +/** An implementing class with incomplete documentation. */ +class C6 implements I1 { + /** Overriding method */ + int m(int p) throws Exception { return p; } +} + +/** A class implementing an inherited interface. */ +class C7 implements I2 { + int m(int p) throws Exception { return p; } +} diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/ReferenceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/ReferenceTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,52 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-reference ReferenceTest.java + * @run main DocLintTester -ref ReferenceTest.out ReferenceTest.java + */ + +/** */ +public class ReferenceTest { + /** + * @param x description + */ + public int invalid_param; + + /** + * @param x description + */ + public class InvalidParam { } + + /** + * @param x description + */ + public void param_name_not_found(int a) { } + + /** + * @param description + */ + public class typaram_name_not_found { } + + /** + * @see Object#tooStrong() + */ + public void ref_not_found() { } + + /** + * @return x description + */ + public int invalid_return; + + /** + * @return x description + */ + public void invalid_return(); + + /** + * @throws Exception description + */ + public void exception_not_thrown() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/ReferenceTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/ReferenceTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,30 @@ +ReferenceTest.java:13: error: invalid use of @param + * @param x description + ^ +ReferenceTest.java:18: error: invalid use of @param + * @param x description + ^ +ReferenceTest.java:23: error: @param name not found + * @param x description + ^ +ReferenceTest.java:25: warning: no @param for a + public void param_name_not_found(int a) { } + ^ +ReferenceTest.java:28: error: @param name not found + * @param description + ^ +ReferenceTest.java:33: error: reference not found + * @see Object#tooStrong() + ^ +ReferenceTest.java:38: error: invalid use of @return + * @return x description + ^ +ReferenceTest.java:43: error: invalid use of @return + * @return x description + ^ +ReferenceTest.java:48: error: exception not thrown: java.lang.Exception + * @throws Exception description + ^ +8 errors +1 warning + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/RunTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/RunTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,105 @@ +/* + * 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 8004832 + * @summary Add new doclint package + * @bug 8000103 + * @summary Create doclint utility + */ + +import com.sun.tools.doclint.DocLint; +import com.sun.tools.doclint.DocLint.BadArgs; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** javadoc error on toplevel: a & b. */ +public class RunTest { + /** javadoc error on member: a < b */ + public static void main(String... args) throws Exception { + new RunTest().run(); + } + + + File testSrc = new File(System.getProperty("test.src")); + File thisFile = new File(testSrc, RunTest.class.getSimpleName() + ".java"); + + void run() throws Exception { + for (Method m: getClass().getDeclaredMethods()) { + Annotation a = m.getAnnotation(Test.class); + if (a != null) { + System.err.println("test: " + m.getName()); + try { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw);; + m.invoke(this, new Object[] { pw }); + String out = sw.toString(); + System.err.println(">>> " + out.replace("\n", "\n>>> ")); + if (!out.contains("a < b")) + error("\"a < b\" not found"); + if (!out.contains("a & b")) + error("\"a & b\" not found"); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + throw (cause instanceof Exception) ? ((Exception) cause) : e; + } + System.err.println(); + } + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; + + /** Marker annotation for test cases. */ + @Retention(RetentionPolicy.RUNTIME) + @interface Test { } + + @Test + void testMain(PrintWriter pw) throws BadArgs, IOException { + String[] args = { "-Xmsgs", thisFile.getPath() }; + DocLint d = new DocLint(); + d.run(pw, args); + } +} + + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/SyntaxTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/SyntaxTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-syntax SyntaxTest.java + * @run main DocLintTester -ref SyntaxTest.out SyntaxTest.java + */ + +/** */ +public class SyntaxTest { + /** + * a < b + */ + public void syntax_error() { } +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/SyntaxTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/SyntaxTest.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,5 @@ +SyntaxTest.java:13: error: malformed HTML + * a < b + ^ +1 error + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/SyntheticTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/SyntheticTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -Xmsgs:all SyntheticTest.java + */ + +/** + * This is a test that messages are not generated for synthesized elements + * such as default constructors and enum methods. + */ +public class SyntheticTest { + // No explicit constructor implies a default constructor + + /** enum E */ + enum E { + /** enum member E1 */ + E1, + /** enum member E2 */ + E2, + /** enum member E3 */ + E3 + } +} + + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/ValidTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/ValidTest.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,112 @@ +/* + * 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 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester ValidTest.java + */ + +class ValidTest { + /** + * < > & ( + */ + void entities() { } + + /** + *

...

+ *

...

+ *

...

+ *

...

+ *
...
+ *
...
+ */ + void all_headers() { } + + /** + *

...

+ *

...

+ *

...

+ *

...

+ *

...

+ *

...

+ *

...

+ */ + void header_series() { } + + /** + *

+ */ + void autoclose_tags() { } + + /** + * @param x + */ + void method_param(int x) { } + + /** + * @param + */ + T method_typaram(T t) { return t; } + + /** + * @param + */ + class ClassTyparam { } + + /** + * @param + */ + interface InterfaceTyparam { } + + /** + * @return x + */ + int return_int() { return 0; } + + /** + * @exception Exception + */ + void throws_Exception1() throws Exception { } + + /** + * @throws Exception + */ + void throws_Exception2() throws Exception { } + + class X { + /** + * @param x + */ + X(int x) { } // constructor parameter + + /** + * @param + */ + X(T t) { } // constructor type parameter + } + +} + diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/AnchorAlreadyDefined.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/AnchorAlreadyDefined.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref AnchorAlreadyDefined.out AnchorAlreadyDefined.java + */ + +// tidy: Warning: <.*> anchor ".*" already defined + +/** + * valid + * duplicate + *

duplicate

+ */ +public class AnchorAlreadyDefined { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/AnchorAlreadyDefined.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/AnchorAlreadyDefined.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,7 @@ +AnchorAlreadyDefined.java:14: error: anchor already defined: here + * duplicate + ^ +AnchorAlreadyDefined.java:15: error: anchor already defined: here + *

duplicate

+ ^ +2 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/BadEnd.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/BadEnd.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref BadEnd.out BadEnd.java + */ + +// tidy: Warning: <.*> is probably intended as + +/** + * text + * text + */ +public class BadEnd { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/BadEnd.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/BadEnd.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,17 @@ +BadEnd.java:14: warning: nested tag not allowed: + * text + ^ +BadEnd.java:14: error: element not closed: code + * text + ^ +BadEnd.java:14: error: element not closed: code + * text + ^ +BadEnd.java:13: error: element not closed: a + * text + ^ +BadEnd.java:13: error: element not closed: a + * text + ^ +4 errors +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InsertImplicit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InsertImplicit.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref InsertImplicit.out InsertImplicit.java + */ + +// tidy: Warning: inserting implicit <.*> + +/** + *

+ *
abc
+ */ +public class InsertImplicit { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InsertImplicit.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InsertImplicit.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,7 @@ +InsertImplicit.java:13: error: unexpected end tag:

+ *

+ ^ +InsertImplicit.java:14: error: block element not allowed within inline element : blockquote + *
abc
+ ^ +2 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidEntity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidEntity.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,22 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref InvalidEntity.out InvalidEntity.java + */ + +// tidy: Warning: replacing invalid numeric character reference .* + +// See +// http://www.w3.org/TR/html4/sgml/entities.html +// http://stackoverflow.com/questions/631406/what-is-the-difference-between-em-dash-151-and-8212 + +/** + *  + *  + * &splodge; + * + */ +public class InvalidEntity { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidEntity.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidEntity.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,10 @@ +InvalidEntity.java:17: error: invalid entity  + *  + ^ +InvalidEntity.java:18: error: invalid entity  + *  + ^ +InvalidEntity.java:19: error: invalid entity &splodge; + * &splodge; + ^ +3 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidName.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,18 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref InvalidName.out InvalidName.java + */ + +// tidy: Warning:
cannot copy name attribute to id + +/** + * valid + * valid + * valid + * invalid + */ +public class InvalidName { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidName.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidName.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +InvalidName.java:16: error: invalid name for anchor: "foo()" + * invalid + ^ +1 error diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidTag.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref InvalidTag.out InvalidTag.java + */ + +// tidy: Error: <.*> is not recognized! + +/** + * List list = new ArrayList<>(); + */ +public class InvalidTag { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidTag.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidTag.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,10 @@ +InvalidTag.java:13: error: unknown tag: String + * List list = new ArrayList<>(); + ^ +InvalidTag.java:13: error: malformed HTML + * List list = new ArrayList<>(); + ^ +InvalidTag.java:13: error: bad use of '>' + * List list = new ArrayList<>(); + ^ +3 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidURI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidURI.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref InvalidURI.out InvalidURI.java + */ + +// tidy: Warning: escaping malformed URI reference +// tidy: Warning: <.*> attribute ".*" lacks value + +/** + * valid + * valid + * invalid + * no value + * no value + * no value + */ +public class InvalidURI { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/InvalidURI.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/InvalidURI.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,13 @@ +InvalidURI.java:16: error: invalid uri: "abc def" + * invalid + ^ +InvalidURI.java:17: error: attribute lacks value + * no value + ^ +InvalidURI.java:18: error: attribute lacks value + * no value + ^ +InvalidURI.java:19: error: attribute lacks value + * no value + ^ +4 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/MissingGT.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/MissingGT.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref MissingGT.out MissingGT.java + */ + +// tidy: Warning: <.*> missing '>' for end of tag + +/** + * text + */ +public class MissingGT { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/MissingGT.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/MissingGT.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +MissingGT.java:13: error: malformed HTML + * +// tidy: Warning: missing before + +/** + *

+ *

text

+ */ +public class MissingTag { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/MissingTag.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/MissingTag.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,7 @@ +MissingTag.java:14: error: unexpected end tag:

+ *

+ ^ +MissingTag.java:15: error: end tag missing:
+ *

text

+ ^ +2 errors diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/NestedTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/NestedTag.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref NestedTag.out NestedTag.java + */ + +// tidy: Warning: nested emphasis <.*> + +/** + * text + * {@link java.lang.String String} + */ +public class NestedTag { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/NestedTag.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/NestedTag.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,7 @@ +NestedTag.java:13: warning: nested tag not allowed: + * text + ^ +NestedTag.java:14: warning: nested tag not allowed: + * {@link java.lang.String String} + ^ +2 warnings diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/ParaInPre.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/ParaInPre.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,20 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref ParaInPre.out ParaInPre.java + */ + +// tidy: Warning: replacing

by
+// tidy: Warning: using
in place of

+ +/** + *

+ *     text
+ *     

+ * more text + *

+ */ +public class ParaInPre { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/ParaInPre.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/ParaInPre.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +ParaInPre.java:16: warning: unexpected use of

inside

 element
+ *     

+ ^ +1 warning diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/README.txt Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,21 @@ +The utilities in this directory can be used to determine +common issues in javadoc comments by running the standard +"tidy" program on the output of javadoc, and analysing +the messages that are reported. + +tidy.sh is a script that will run the "tidy" program on +the files in a directory, writing the results to a new +directroy. + +tidystats.Main is a Java program that can analyze the +files produced by the tidy.sh script to generate a +summary report about the warnings that were found. + + +The tests is this directory are focussed on verifying +that doclint detects issues in javadoc comments that will +give rise to issues detected by "tidy" in the output +generated by javadoc. + +For more information on the "tidy" program, see the HTML Tidy +Library Project page at http://tidy.sourceforge.net/. diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/RepeatedAttr.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/RepeatedAttr.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref RepeatedAttr.out RepeatedAttr.java + */ + +// tidy: Warning: <.*> dropping value ".*" for repeated attribute ".*" + +/** + * + */ +public class RepeatedAttr { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/RepeatedAttr.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/RepeatedAttr.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,4 @@ +RepeatedAttr.java:13: error: repeated attribute: alt + * + ^ +1 error diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/TextNotAllowed.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/TextNotAllowed.java Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,26 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @library .. + * @build DocLintTester + * @run main DocLintTester -ref TextNotAllowed.out TextNotAllowed.java + */ + +// tidy: Warning: plain text isn't allowed in <.*> elements + +/** + * abc
+ * abc
+ * abc
+ * + *

abc
+ *
    abc
+ *
    abc
+ * + *
    + *
  • item + *
  • item + *
+ */ +public class TextNotAllowed { } diff -r 7d5032c2d747 -r 467e4d9281bc test/tools/doclint/tidy/TextNotAllowed.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/doclint/tidy/TextNotAllowed.out Fri Dec 28 18:39:09 2012 -0800 @@ -0,0 +1,19 @@ +TextNotAllowed.java:13: error: text not allowed in element + *
abc
+ ^ +TextNotAllowed.java:14: error: text not allowed in element + * abc
+ ^ +TextNotAllowed.java:15: error: text not allowed in element + * abc
+ ^ +TextNotAllowed.java:17: error: text not allowed in
element + *
abc
+ ^ +TextNotAllowed.java:18: error: text not allowed in
    element + *
      abc
    + ^ +TextNotAllowed.java:19: error: text not allowed in