--- a/langtools/make/build.properties Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/make/build.properties Mon Dec 17 07:47:05 2012 -0800
@@ -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
--- a/langtools/src/share/classes/com/sun/source/util/DocTrees.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/DocTrees.java Mon Dec 17 07:47:05 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);
}
/**
--- a/langtools/src/share/classes/com/sun/source/util/JavacTask.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/JavacTask.java Mon Dec 17 07:47:05 2012 -0800
@@ -139,6 +139,7 @@
* @see com.sun.source.util.Trees#getTypeMirror
*/
public abstract TypeMirror getTypeMirror(Iterable<? extends Tree> path);
+
/**
* Get a utility object for dealing with program elements.
*/
--- a/langtools/src/share/classes/com/sun/source/util/TreePath.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/TreePath.java Mon Dec 17 07:47:05 2012 -0800
@@ -60,14 +60,20 @@
this.path = path;
}
}
+
class PathFinder extends TreePathScanner<TreePath,Tree> {
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) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Mon Dec 17 07:47:05 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Checker extends DocTreeScanner<Void, Void> {
+ final Env env;
+
+ Set<Element> foundParams = new HashSet<Element>();
+ Set<TypeMirror> foundThrows = new HashSet<TypeMirror>();
+ Set<String> foundAnchors = new HashSet<String>();
+ 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<HtmlTag.Attr> attrs;
+ final Set<Flag> 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<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well
+ private HtmlTag currHeaderTag;
+
+ // <editor-fold defaultstate="collapsed" desc="Top level">
+
+ Checker(Env env) {
+ env.getClass();
+ this.env = env;
+ tagStack = new LinkedList<TagStackItem>();
+ }
+
+ 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;
+ }
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="Text and entities.">
+
+ @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;
+ }
+
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="HTML elements">
+
+ @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 <h1>...</h1> <h3>...</h3>
+ case H1: case H2: case H3: case H4: case H5: case H6:
+ checkHeader(tree, t);
+ break;
+ // <p> inside <pre>
+ case P:
+ TagStackItem top = tagStack.peek();
+ if (top != null && top.tag == HtmlTag.PRE)
+ env.messages.warning(HTML, tree, "dc.tag.p.in.pre");
+ break;
+ }
+
+ // check that only block tags and inline tags are used,
+ // and that blocks tags are not used within inline tags
+ switch (t.blockType) {
+ case INLINE:
+ break;
+ case BLOCK:
+ TagStackItem top = tagStack.peek();
+ if (top != null && top.tag != null && top.tag.blockType == HtmlTag.BlockType.INLINE) {
+ switch (top.tree.getKind()) {
+ case START_ELEMENT: {
+ Name name = ((StartElementTree) top.tree).getName();
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
+ treeName, name);
+ break;
+ }
+ case LINK:
+ case LINK_PLAIN: {
+ String name = top.tree.getKind().tagName;
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
+ treeName, name);
+ break;
+ }
+ default:
+ env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.other",
+ treeName);
+ }
+ }
+ break;
+ case OTHER:
+ env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+ break;
+ default:
+ throw new AssertionError();
+ }
+
+ if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
+ 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 <a id="name"/>
+ 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);
+ }
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="HTML attributes">
+
+ @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);
+ }
+ }
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="javadoc tags">
+
+ @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<? extends Element> 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<? extends Element> 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<? extends TypeMirror> 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<? extends TypeMirror> 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;
+ }
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="Utility methods">
+
+ 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<? extends DocTree> 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);
+ }
+ // </editor-fold>
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Mon Dec 17 07:47:05 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:
+ * <ul>
+ * <li>From the command line
+ * <li>From javac, as a plugin
+ * <li>Directly, via a simple API
+ * </ul>
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class DocLint implements Plugin {
+
+ public static final String XMSGS_OPTION = "-Xmsgs";
+ public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:";
+ private static final String STATS = "-stats";
+
+ // <editor-fold defaultstate="collapsed" desc="Command-line entry point">
+ 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);
+ }
+ }
+
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="Simple API">
+
+ 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<? extends CompilationUnitTree> 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<String>();
+ javacFiles = new ArrayList<File>();
+
+ 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<File> splitPath(String path) {
+ List<File> files = new ArrayList<File>();
+ for (String f: path.split(File.separator)) {
+ if (f.length() > 0)
+ files.add(new File(f));
+ }
+ return files;
+ }
+
+ List<File> javacBootClassPath;
+ List<File> javacClassPath;
+ List<File> javacSourcePath;
+ List<String> javacOpts;
+ List<File> javacFiles;
+ boolean needHelp = false;
+
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="javac Plugin">
+
+ @Override
+ public String getName() {
+ return "doclint";
+ }
+
+ @Override
+ public void call(JavacTask task, String... args) {
+ init(task, args, true);
+ }
+
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="Embedding API">
+
+ 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);
+ }
+
+ // </editor-fold>
+
+ 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;
+ }
+
+ // <editor-fold defaultstate="collapsed" desc="DeclScanner">
+
+ static abstract class DeclScanner extends TreePathScanner<Void, Void> {
+ 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);
+ }
+ }
+
+ // </editor-fold>
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Entity.java Mon Dec 17 07:47:05 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.
+ *
+ * <p> Derived from
+ * <a href="http://www.w3.org/TR/html4/sgml/entities.html">Character entity references in HTML 4</a>.
+ *
+ * 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 '_'.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+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<String,Entity> names = new HashMap<String,Entity>();
+ private static final Map<Integer,Entity> codes = new HashMap<Integer,Entity>();
+ 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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Env.java Mon Dec 17 07:47:05 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class 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<Modifier> 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<? extends ExecutableElement> 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 extends Comparable<T>> T min(T item1, T item2) {
+ return (item1 == null) ? item2
+ : (item2 == null) ? item1
+ : item1.compareTo(item2) <= 0 ? item1 : item2;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java Mon Dec 17 07:47:05 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 <a href="http://www.w3.org/TR/REC-html40/">HTML 4.01 Specification</a>
+ * @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<String,Attr> index = new HashMap<String,Attr>();
+ 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<Attr,AttrKind> in signature of HtmlTag constructor.
+ private static class AttrMap extends EnumMap<Attr,AttrKind> {
+ private static final long serialVersionUID = 0;
+ AttrMap() {
+ super(Attr.class);
+ }
+ }
+
+
+ public final BlockType blockType;
+ public final EndKind endKind;
+ public final Set<Flag> flags;
+ private final Map<Attr,AttrKind> attrs;
+
+
+ HtmlTag() {
+ this(BlockType.BLOCK, EndKind.REQUIRED);
+ }
+
+ HtmlTag(Set<Flag> flags) {
+ this(BlockType.BLOCK, EndKind.REQUIRED, flags);
+ }
+
+ HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) {
+ this(blockType, endKind, Collections.<Flag>emptySet(), attrMaps);
+ }
+
+ HtmlTag(BlockType blockType, EndKind endKind, Set<Flag> flags, AttrMap... attrMaps) {
+ this.blockType = blockType;
+ this.endKind = endKind;this.flags = flags;
+ this.attrs = new EnumMap<Attr,AttrKind>(Attr.class);
+ for (Map<Attr,AttrKind> 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<String,HtmlTag> index = new HashMap<String,HtmlTag>();
+ static {
+ for (HtmlTag t: values()) {
+ index.put(t.name().toLowerCase(), t);
+ }
+ }
+
+ static HtmlTag get(Name tagName) {
+ return index.get(tagName.toString().toLowerCase());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Messages.java Mon Dec 17 07:47:05 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.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class 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);
+ }
+
+ // <editor-fold defaultstate="collapsed" desc="Options">
+
+ /**
+ * Handler for (sub)options specific to message handling.
+ */
+ static class Options {
+ Map<String, Env.AccessKind> map = new HashMap<String, Env.AccessKind>();
+ 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";
+ }
+
+ // </editor-fold>
+
+ // <editor-fold defaultstate="collapsed" desc="Statistics">
+
+ /**
+ * 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<String, Integer> 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<String, Integer>();
+ } 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<String, Integer> 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<Integer> DECREASING = new Comparator<Integer>() {
+
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ };
+ private final TreeMap<Integer, Set<String>> map = new TreeMap<Integer, Set<String>>(DECREASING);
+
+ void put(String label, int n) {
+ if (n == 0) {
+ return;
+ }
+ Set<String> labels = map.get(n);
+ if (labels == null) {
+ map.put(n, labels = new TreeSet<String>());
+ }
+ labels.add(label);
+ }
+
+ void print(PrintWriter out) {
+ for (Map.Entry<Integer, Set<String>> e : map.entrySet()) {
+ int count = e.getKey();
+ Set<String> labels = e.getValue();
+ for (String label : labels) {
+ out.println(String.format("%6d: %s", count, label));
+ }
+ }
+ }
+ }
+ }
+ // </editor-fold>
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Mon Dec 17 07:47:05 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: </{0}>
+dc.tag.end.unexpected = unexpected end tag: </{0}>
+dc.tag.header.sequence.1 = header used out of sequence: <{0}>
+dc.tag.header.sequence.2 = header used out of sequence: <{0}>
+dc.tag.nested.not.allowed=nested tag not allowed: <{0}>
+dc.tag.not.allowed = 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 <p> inside <pre> element
+dc.tag.self.closing = self-closing element not allowed
+dc.tag.start.unmatched = end tag missing: </{0}>
+dc.tag.unknown = unknown tag: {0}
+dc.text.not.allowed = text not allowed in <{0}> element
--- a/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Mon Dec 17 07:47:05 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)
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Mon Dec 17 07:47:05 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<JavaFileObject> fileObjects) {
super(null, false);
- this.ccw = ClientCodeWrapper.instance(context);
this.compilerMain = compilerMain;
this.args = args;
this.classNames = classNames;
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Mon Dec 17 07:47:05 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);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Dec 17 07:47:05 2012 -0800
@@ -1675,7 +1675,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)
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Dec 17 07:47:05 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<MethodSymbol> 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<MethodSymbol> results = new LinkedHashSet<MethodSymbol>();
+ 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;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Mon Dec 17 07:47:05 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<DCTree> 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);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Dec 17 07:47:05 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 '@'
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/DCTree.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DCTree.java Mon Dec 17 07:47:05 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
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/DocPretty.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DocPretty.java Mon Dec 17 07:47:05 2012 -0800
@@ -81,7 +81,7 @@
/**
* Print list.
*/
- protected void print(List<? extends DocTree> list) throws IOException {
+ public void print(List<? extends DocTree> list) throws IOException {
for (DocTree t: list) {
print(t);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Mon Dec 17 14:54:42 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Mon Dec 17 07:47:05 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.
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,63 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessTest.package.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,20 @@
+AccessTest.java:21: error: malformed HTML
+ * public a < b
+ ^
+AccessTest.java:26: error: malformed HTML
+ * protected a < b
+ ^
+AccessTest.java:31: error: malformed HTML
+ * package-private a < b
+ ^
+AccessTest.java:44: error: malformed HTML
+ * public a < b
+ ^
+AccessTest.java:49: error: malformed HTML
+ * protected a < b
+ ^
+AccessTest.java:54: error: malformed HTML
+ * package-private a < b
+ ^
+6 errors
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessTest.private.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,27 @@
+AccessTest.java:21: error: malformed HTML
+ * public a < b
+ ^
+AccessTest.java:26: error: malformed HTML
+ * protected a < b
+ ^
+AccessTest.java:31: error: malformed HTML
+ * package-private a < b
+ ^
+AccessTest.java:36: error: malformed HTML
+ * private a < b
+ ^
+AccessTest.java:44: error: malformed HTML
+ * public a < b
+ ^
+AccessTest.java:49: error: malformed HTML
+ * protected a < b
+ ^
+AccessTest.java:54: error: malformed HTML
+ * package-private a < b
+ ^
+AccessTest.java:59: error: malformed HTML
+ * private a < b
+ ^
+8 errors
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessTest.protected.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,8 @@
+AccessTest.java:21: error: malformed HTML
+ * public a < b
+ ^
+AccessTest.java:26: error: malformed HTML
+ * protected a < b
+ ^
+2 errors
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessTest.public.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+AccessTest.java:21: error: malformed HTML
+ * public a < b
+ ^
+1 error
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessibilityTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * @test /nodynamiccopyright/
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-accessibility AccessibilityTest.java
+ * @run main DocLintTester -ref AccessibilityTest.out AccessibilityTest.java
+ */
+
+/** */
+public class AccessibilityTest {
+
+ /**
+ * <h2> ... </h2>
+ */
+ public void missing_h1() { }
+
+ /**
+ * <h1> ... </h1>
+ * <h3> ... </h3>
+ */
+ public void missing_h2() { }
+
+ /**
+ * <img src="x.jpg">
+ */
+ public void missing_alt() { }
+
+ /**
+ * <table summary="ok"><tr><th>head<tr><td>data</table>
+ */
+ public void table_with_summary() { }
+
+ /**
+ * <table><caption>ok</caption><tr><th>head<tr><td>data</table>
+ */
+ public void table_with_caption() { }
+
+ /**
+ * <table><tr><th>head<tr><td>data</table>
+ */
+ public void table_without_summary_and_caption() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AccessibilityTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,13 @@
+AccessibilityTest.java:12: error: header used out of sequence: <H2>
+ * <h2> ... </h2>
+ ^
+AccessibilityTest.java:18: error: header used out of sequence: <H3>
+ * <h3> ... </h3>
+ ^
+AccessibilityTest.java:23: error: no "alt" attribute for image
+ * <img src="x.jpg">
+ ^
+AccessibilityTest.java:38: error: no summary or caption for table
+ * <table><tr><th>head<tr><td>data</table>
+ ^
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/DocLintTester.java Mon Dec 17 07:47:05 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<String> opts = new ArrayList<String>();
+ List<File> files = new ArrayList<File>();
+ 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<String> opts, List<File> files, File refFile) throws Exception {
+ List<String> args = new ArrayList<String>();
+ 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyAuthorTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-syntax EmptyAuthorTest.java
+ * @run main DocLintTester -Xmsgs:syntax -ref EmptyAuthorTest.out EmptyAuthorTest.java
+ */
+
+/** @author */
+public class EmptyAuthorTest {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyAuthorTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptyAuthorTest.java:8: warning: no description for @author
+/** @author */
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyExceptionTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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 { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyExceptionTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+EmptyExceptionTest.java:10: warning: no description for @exception
+ /** @exception NullPointerException */
+ ^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyParamTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyParamTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptyParamTest.java:10: warning: no description for @param
+ /** @param i */
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyReturnTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyReturnTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptyReturnTest.java:10: warning: no description for @return
+ /** @return */
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySerialDataTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySerialDataTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptySerialDataTest.java:13: warning: no description for @serialData
+ /** @serialData */
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySerialFieldTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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),
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySerialFieldTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptySerialFieldTest.java:15: warning: no description for @serialField
+ * @serialField empty String
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySinceTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptySinceTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+EmptySinceTest.java:10: warning: no description for @since
+ /** @since */
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyVersionTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EmptyVersionTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+EmptyVersionTest.java:10: warning: no description for @version
+ /** @version */
+ ^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/HtmlAttrsTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html HtmlAttrsTest.java
+ * @run main DocLintTester -ref HtmlAttrsTest.out HtmlAttrsTest.java
+ */
+
+/** */
+public class HtmlAttrsTest {
+ /**
+ * <p xyz>
+ */
+ public void unknown() { }
+
+ /**
+ * <img name="x" alt="alt">
+ */
+ public void obsolete() { }
+
+ /**
+ * <font size="3"> text </font>
+ */
+ public void obsolete_use_css() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/HtmlAttrsTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+HtmlAttrsTest.java:11: error: unknown attribute: xyz
+ * <p xyz>
+ ^
+HtmlAttrsTest.java:16: warning: attribute obsolete: name
+ * <img name="x" alt="alt">
+ ^
+HtmlAttrsTest.java:21: warning: attribute obsolete, use CSS instead: size
+ * <font size="3"> text </font>
+ ^
+1 error
+2 warnings
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/HtmlTagsTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * @test /nodynamiccopyright/
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html HtmlTagsTest.java
+ * @run main DocLintTester -ref HtmlTagsTest.out HtmlTagsTest.java
+ */
+
+/** */
+public class HtmlTagsTest {
+ /**
+ * <xyz> ... </xyz>
+ */
+ public void unknownTag1() { }
+
+ /**
+ * <div> <xyz> </div>
+ */
+ public void unknownTag2() { }
+
+ /**
+ * <br/>
+ */
+ public void selfClosingTag() { }
+
+ /**
+ * <html>
+ */
+ public void not_allowed() { }
+
+ /**
+ * <span> <p> </span>
+ */
+ public void not_allowed_inline() { }
+
+ /**
+ * {@link java.lang.String <p> }
+ * {@link java.lang.String <p> }
+ */
+ public void not_allowed_inline_2() { }
+
+ /**
+ * <img src="any.jpg" alt="alt"> </img>
+ */
+ public void end_not_allowed() { }
+
+ /**
+ * <i> <b> </i>
+ */
+ public void start_not_matched() { }
+
+ /**
+ * <i> </b> </i>
+ */
+ public void end_unexpected() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/HtmlTagsTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,38 @@
+HtmlTagsTest.java:11: error: unknown tag: xyz
+ * <xyz> ... </xyz>
+ ^
+HtmlTagsTest.java:11: error: unknown tag: xyz
+ * <xyz> ... </xyz>
+ ^
+HtmlTagsTest.java:16: error: unknown tag: xyz
+ * <div> <xyz> </div>
+ ^
+HtmlTagsTest.java:21: error: self-closing element not allowed
+ * <br/>
+ ^
+HtmlTagsTest.java:26: error: element not allowed in documentation comments: <html>
+ * <html>
+ ^
+HtmlTagsTest.java:31: error: block element not allowed within inline element <span>: p
+ * <span> <p> </span>
+ ^
+HtmlTagsTest.java:36: error: block element not allowed within @link: p
+ * {@link java.lang.String <p> }
+ ^
+HtmlTagsTest.java:37: error: block element not allowed within @link: p
+ * {@link java.lang.String <p> }
+ ^
+HtmlTagsTest.java:42: error: invalid end tag: </img>
+ * <img src="any.jpg" alt="alt"> </img>
+ ^
+HtmlTagsTest.java:47: error: end tag missing: </b>
+ * <i> <b> </i>
+ ^
+HtmlTagsTest.java:52: error: unexpected end tag: </b>
+ * <i> </b> </i>
+ ^
+HtmlTagsTest.java:52: warning: empty <i> tag
+ * <i> </b> </i>
+ ^
+11 errors
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingCommentTest.java Mon Dec 17 07:47:05 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() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingCommentTest.out Mon Dec 17 07:47:05 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingParamsTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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) { }
+
+ /** */
+ <T> MissingParamsTest() { }
+
+ /** */
+ void missingParam(int param) { }
+
+ /** */
+ <T> void missingTyparam() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingParamsTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,14 @@
+MissingParamsTest.java:11: warning: no @param for param
+ MissingParamsTest(int param) { }
+ ^
+MissingParamsTest.java:14: warning: no @param for <T>
+ <T> MissingParamsTest() { }
+ ^
+MissingParamsTest.java:17: warning: no @param for param
+ void missingParam(int param) { }
+ ^
+MissingParamsTest.java:20: warning: no @param for <T>
+ <T> void missingTyparam() { }
+ ^
+4 warnings
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingReturnTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingReturnTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+MissingReturnTest.java:20: warning: no @return
+ int missingReturn() { }
+ ^
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingThrowsTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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 { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/MissingThrowsTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+MissingThrowsTest.java:11: warning: no @throws for java.lang.Exception
+ void missingThrows() throws Exception { }
+ ^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/OptionTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,94 @@
+
+import com.sun.tools.doclint.DocLint;
+
+/*
+ * 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
+ */
+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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/OverridesTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,91 @@
+/*
+ * 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
+ * @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; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/ReferenceTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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 <X> 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() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/ReferenceTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,30 @@
+ReferenceTest.java:11: error: invalid use of @param
+ * @param x description
+ ^
+ReferenceTest.java:16: error: invalid use of @param
+ * @param x description
+ ^
+ReferenceTest.java:21: error: @param name not found
+ * @param x description
+ ^
+ReferenceTest.java:23: warning: no @param for a
+ public void param_name_not_found(int a) { }
+ ^
+ReferenceTest.java:26: error: @param name not found
+ * @param <X> description
+ ^
+ReferenceTest.java:31: error: reference not found
+ * @see Object#tooStrong()
+ ^
+ReferenceTest.java:36: error: invalid use of @return
+ * @return x description
+ ^
+ReferenceTest.java:41: error: invalid use of @return
+ * @return x description
+ ^
+ReferenceTest.java:46: error: exception not thrown: java.lang.Exception
+ * @throws Exception description
+ ^
+8 errors
+1 warning
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/RunTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,103 @@
+/*
+ * 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 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);
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/SyntaxTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/SyntaxTest.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,5 @@
+SyntaxTest.java:11: error: malformed HTML
+ * a < b
+ ^
+1 error
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/SyntheticTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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
+ * @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
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/ValidTest.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,110 @@
+/*
+ * 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
+ * @build DocLintTester
+ * @run main DocLintTester ValidTest.java
+ */
+
+class ValidTest {
+ /**
+ * < > & (
+ */
+ void entities() { }
+
+ /**
+ * <h1> ... </h1>
+ * <h2> ... </h2>
+ * <h3> ... </h3>
+ * <h4> ... </h4>
+ * <h5> ... </h5>
+ * <h6> ... </h6>
+ */
+ void all_headers() { }
+
+ /**
+ * <h1> ... </h1>
+ * <h2> ... </h2>
+ * <h3> ... </h3>
+ * <h1> ... </h1>
+ * <h2> ... </h2>
+ * <h3> ... </h3>
+ * <h2> ... </h2>
+ */
+ void header_series() { }
+
+ /**
+ * <div> <p> </div>
+ */
+ void autoclose_tags() { }
+
+ /**
+ * @param x
+ */
+ void method_param(int x) { }
+
+ /**
+ * @param <T>
+ */
+ <T> T method_typaram(T t) { return t; }
+
+ /**
+ * @param <T>
+ */
+ class ClassTyparam<T> { }
+
+ /**
+ * @param <T>
+ */
+ interface InterfaceTyparam<T> { }
+
+ /**
+ * @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 <T>
+ */
+ <T> X(T t) { } // constructor type parameter
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref AnchorAlreadyDefined.out AnchorAlreadyDefined.java
+ */
+
+// tidy: Warning: <.*> anchor ".*" already defined
+
+/**
+ * <a name="here">valid</a>
+ * <a name="here">duplicate</a>
+ * <h1 id="here">duplicate</h1>
+ */
+public class AnchorAlreadyDefined { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,7 @@
+AnchorAlreadyDefined.java:12: error: anchor already defined: here
+ * <a name="here">duplicate</a>
+ ^
+AnchorAlreadyDefined.java:13: error: anchor already defined: here
+ * <h1 id="here">duplicate</h1>
+ ^
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/BadEnd.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref BadEnd.out BadEnd.java
+ */
+
+// tidy: Warning: <.*> is probably intended as </.*>
+
+/**
+ * <a name="here"> text <a>
+ * <code> text <code>
+ */
+public class BadEnd { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/BadEnd.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,17 @@
+BadEnd.java:12: warning: nested tag not allowed: <code>
+ * <code> text <code>
+ ^
+BadEnd.java:12: error: element not closed: code
+ * <code> text <code>
+ ^
+BadEnd.java:12: error: element not closed: code
+ * <code> text <code>
+ ^
+BadEnd.java:11: error: element not closed: a
+ * <a name="here"> text <a>
+ ^
+BadEnd.java:11: error: element not closed: a
+ * <a name="here"> text <a>
+ ^
+4 errors
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InsertImplicit.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref InsertImplicit.out InsertImplicit.java
+ */
+
+// tidy: Warning: inserting implicit <.*>
+
+/**
+ * </p>
+ * <i> <blockquote> abc </blockquote> </i>
+ */
+public class InsertImplicit { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InsertImplicit.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,7 @@
+InsertImplicit.java:11: error: unexpected end tag: </p>
+ * </p>
+ ^
+InsertImplicit.java:12: error: block element not allowed within inline element <i>: blockquote
+ * <i> <blockquote> abc </blockquote> </i>
+ ^
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidEntity.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidEntity.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,10 @@
+InvalidEntity.java:15: error: invalid entity 
+ * 
+ ^
+InvalidEntity.java:16: error: invalid entity 
+ * 
+ ^
+InvalidEntity.java:17: error: invalid entity &splodge;
+ * &splodge;
+ ^
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidName.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref InvalidName.out InvalidName.java
+ */
+
+// tidy: Warning: <a> cannot copy name attribute to id
+
+/**
+ * <a name="abc">valid</a>
+ * <a name="abc123">valid</a>
+ * <a name="a.1:2-3_4">valid</a>
+ * <a name="foo()">invalid</a>
+ */
+public class InvalidName { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidName.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+InvalidName.java:14: error: invalid name for anchor: "foo()"
+ * <a name="foo()">invalid</a>
+ ^
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidTag.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref InvalidTag.out InvalidTag.java
+ */
+
+// tidy: Error: <.*> is not recognized!
+
+/**
+ * List<String> list = new ArrayList<>();
+ */
+public class InvalidTag { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidTag.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,10 @@
+InvalidTag.java:11: error: unknown tag: String
+ * List<String> list = new ArrayList<>();
+ ^
+InvalidTag.java:11: error: malformed HTML
+ * List<String> list = new ArrayList<>();
+ ^
+InvalidTag.java:11: error: bad use of '>'
+ * List<String> list = new ArrayList<>();
+ ^
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidURI.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref InvalidURI.out InvalidURI.java
+ */
+
+// tidy: Warning: <a> escaping malformed URI reference
+// tidy: Warning: <.*> attribute ".*" lacks value
+
+/**
+ * <a href="abc">valid</a>
+ * <a href="abc%20def">valid</a>
+ * <a href="abc def">invalid</a>
+ * <a href>no value</a>
+ * <a href= >no value</a>
+ * <a href="" >no value</a>
+ */
+public class InvalidURI { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/InvalidURI.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,13 @@
+InvalidURI.java:14: error: invalid uri: "abc def"
+ * <a href="abc def">invalid</a>
+ ^
+InvalidURI.java:15: error: attribute lacks value
+ * <a href>no value</a>
+ ^
+InvalidURI.java:16: error: attribute lacks value
+ * <a href= >no value</a>
+ ^
+InvalidURI.java:17: error: attribute lacks value
+ * <a href="" >no value</a>
+ ^
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/MissingGT.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref MissingGT.out MissingGT.java
+ */
+
+// tidy: Warning: <.*> missing '>' for end of tag
+
+/**
+ * <img src="image.gif"
+ * <i> text </i>
+ */
+public class MissingGT { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/MissingGT.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+MissingGT.java:11: error: malformed HTML
+ * <img src="image.gif"
+ ^
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/MissingTag.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref MissingTag.out MissingTag.java
+ */
+
+// tidy: Warning: missing <.*>
+// tidy: Warning: missing </.*> before </.*>
+
+/**
+ * </p>
+ * <h1> <b> text </h1>
+ */
+public class MissingTag { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/MissingTag.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,7 @@
+MissingTag.java:12: error: unexpected end tag: </p>
+ * </p>
+ ^
+MissingTag.java:13: error: end tag missing: </b>
+ * <h1> <b> text </h1>
+ ^
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/NestedTag.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref NestedTag.out NestedTag.java
+ */
+
+// tidy: Warning: nested emphasis <.*>
+
+/**
+ * <b><b> text </b></b>
+ * {@link java.lang.String <code>String</code>}
+ */
+public class NestedTag { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/NestedTag.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,7 @@
+NestedTag.java:11: warning: nested tag not allowed: <b>
+ * <b><b> text </b></b>
+ ^
+NestedTag.java:12: warning: nested tag not allowed: <code>
+ * {@link java.lang.String <code>String</code>}
+ ^
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/ParaInPre.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref ParaInPre.out ParaInPre.java
+ */
+
+// tidy: Warning: replacing <p> by <br>
+// tidy: Warning: using <br> in place of <p>
+
+/**
+ * <pre>
+ * text
+ * <p>
+ * more text
+ * </pre>
+ */
+public class ParaInPre { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/ParaInPre.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+ParaInPre.java:14: warning: unexpected use of <p> inside <pre> element
+ * <p>
+ ^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/README.txt Mon Dec 17 07:47:05 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/.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/RepeatedAttr.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref RepeatedAttr.out RepeatedAttr.java
+ */
+
+// tidy: Warning: <.*> dropping value ".*" for repeated attribute ".*"
+
+/**
+ * <img src="image.gif" alt alt="summary">
+ */
+public class RepeatedAttr { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/RepeatedAttr.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,4 @@
+RepeatedAttr.java:11: error: repeated attribute: alt
+ * <img src="image.gif" alt alt="summary">
+ ^
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/TextNotAllowed.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref TextNotAllowed.out TextNotAllowed.java
+ */
+
+// tidy: Warning: plain text isn't allowed in <.*> elements
+
+/**
+ * <table summary=description> abc </table>
+ * <table summary=description> <tbody> abc </tbody> </table>
+ * <table summary=description> <tr> abc </tr> </table>
+ *
+ * <dl> abc </dl>
+ * <ol> abc </ol>
+ * <ul> abc </ul>
+ *
+ * <ul>
+ * <li> item
+ * <li> item
+ * </ul>
+ */
+public class TextNotAllowed { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/TextNotAllowed.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,19 @@
+TextNotAllowed.java:11: error: text not allowed in <table> element
+ * <table summary=description> abc </table>
+ ^
+TextNotAllowed.java:12: error: text not allowed in <tbody> element
+ * <table summary=description> <tbody> abc </tbody> </table>
+ ^
+TextNotAllowed.java:13: error: text not allowed in <tr> element
+ * <table summary=description> <tr> abc </tr> </table>
+ ^
+TextNotAllowed.java:15: error: text not allowed in <dl> element
+ * <dl> abc </dl>
+ ^
+TextNotAllowed.java:16: error: text not allowed in <ol> element
+ * <ol> abc </ol>
+ ^
+TextNotAllowed.java:17: error: text not allowed in <ul> element
+ * <ul> abc </ul>
+ ^
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref TrimmingEmptyTag.out TrimmingEmptyTag.java
+ */
+
+// tidy: Warning: trimming empty <.*>
+
+/**
+ * <b></b>
+ * <table summary=description></table>
+ * <table><caption></caption></table>
+ * <code></code>
+ * <dl></dl>
+ * <dl><dt></dt><dd></dd></dl>
+ * <font></font>
+ * <i></i>
+ * <ol></ol>
+ * <p></p>
+ * <pre></pre>
+ * <span></span>
+ * <tt></tt>
+ * <ul></ul>
+ * <ul><li></li></ul>
+ */
+public class TrimmingEmptyTag { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,46 @@
+TrimmingEmptyTag.java:11: warning: empty <b> tag
+ * <b></b>
+ ^
+TrimmingEmptyTag.java:12: warning: empty <table> tag
+ * <table summary=description></table>
+ ^
+TrimmingEmptyTag.java:13: warning: empty <caption> tag
+ * <table><caption></caption></table>
+ ^
+TrimmingEmptyTag.java:14: warning: empty <code> tag
+ * <code></code>
+ ^
+TrimmingEmptyTag.java:15: warning: empty <dl> tag
+ * <dl></dl>
+ ^
+TrimmingEmptyTag.java:16: warning: empty <dt> tag
+ * <dl><dt></dt><dd></dd></dl>
+ ^
+TrimmingEmptyTag.java:16: warning: empty <dd> tag
+ * <dl><dt></dt><dd></dd></dl>
+ ^
+TrimmingEmptyTag.java:17: warning: empty <font> tag
+ * <font></font>
+ ^
+TrimmingEmptyTag.java:18: warning: empty <i> tag
+ * <i></i>
+ ^
+TrimmingEmptyTag.java:19: warning: empty <ol> tag
+ * <ol></ol>
+ ^
+TrimmingEmptyTag.java:20: warning: empty <p> tag
+ * <p></p>
+ ^
+TrimmingEmptyTag.java:21: warning: empty <pre> tag
+ * <pre></pre>
+ ^
+TrimmingEmptyTag.java:22: warning: empty <span> tag
+ * <span></span>
+ ^
+TrimmingEmptyTag.java:23: warning: empty <tt> tag
+ * <tt></tt>
+ ^
+TrimmingEmptyTag.java:24: warning: empty <ul> tag
+ * <ul></ul>
+ ^
+15 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/UnescapedOrUnknownEntity.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @library ..
+ * @build DocLintTester
+ * @run main DocLintTester -ref UnescapedOrUnknownEntity.out UnescapedOrUnknownEntity.java
+ */
+
+// tidy: Warning: unescaped & or unknown entity ".*"
+// tidy: Warning: unescaped & which should be written as &
+// tidy: Warning: entity ".*" doesn't end in ';'
+
+/**
+ * L&F
+ * Drag&Drop
+ * if (a & b);
+ */
+public class UnescapedOrUnknownEntity { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/UnescapedOrUnknownEntity.out Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,11 @@
+UnescapedOrUnknownEntity.java:13: error: semicolon missing
+ * L&F
+ ^
+UnescapedOrUnknownEntity.java:14: error: semicolon missing
+ * Drag&Drop
+ ^
+UnescapedOrUnknownEntity.java:15: error: bad HTML entity
+ * if (a & b);
+ ^
+3 errors
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/util/Main.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,182 @@
+package tidystats;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Main {
+ public static void main(String... args) throws IOException {
+ new Main().run(args);
+ }
+
+ void run(String... args) throws IOException {
+ FileSystem fs = FileSystems.getDefault();
+ List<Path> paths = new ArrayList<>();
+
+ int i;
+ for (i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if (arg.startsWith("-"))
+ throw new IllegalArgumentException(arg);
+ else
+ break;
+ }
+
+ for ( ; i < args.length; i++) {
+ Path p = fs.getPath(args[i]);
+ paths.add(p);
+ }
+
+ for (Path p: paths) {
+ scan(p);
+ }
+
+ print("%6d files read", files);
+ print("%6d files had no errors or warnings", ok);
+ print("%6d files reported \"Not all warnings/errors were shown.\"", overflow);
+ print("%6d errors found", errs);
+ print("%6d warnings found", warns);
+ print("%6d recommendations to use CSS", css);
+ print("");
+
+ Map<Integer, Set<String>> sortedCounts = new TreeMap<>(
+ new Comparator<Integer>() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ });
+
+ for (Map.Entry<Pattern, Integer> e: counts.entrySet()) {
+ Pattern p = e.getKey();
+ Integer n = e.getValue();
+ Set<String> set = sortedCounts.get(n);
+ if (set == null)
+ sortedCounts.put(n, (set = new TreeSet<>()));
+ set.add(p.toString());
+ }
+
+ for (Map.Entry<Integer, Set<String>> e: sortedCounts.entrySet()) {
+ for (String p: e.getValue()) {
+ if (p.startsWith(".*")) p = p.substring(2);
+ print("%6d: %s", e.getKey(), p);
+ }
+ }
+ }
+
+ void scan(Path p) throws IOException {
+ if (Files.isDirectory(p)) {
+ for (Path c: Files.newDirectoryStream(p)) {
+ scan(c);
+ }
+ } else if (isTidyFile(p)) {
+ scan(Files.readAllLines(p, Charset.defaultCharset()));
+ }
+ }
+
+ boolean isTidyFile(Path p) {
+ return Files.isRegularFile(p) && p.getFileName().toString().endsWith(".tidy");
+ }
+
+ void scan(List<String> lines) {
+ Matcher m;
+ files++;
+ for (String line: lines) {
+ if (okPattern.matcher(line).matches()) {
+ ok++;
+ } else if ((m = countPattern.matcher(line)).matches()) {
+ warns += Integer.valueOf(m.group(1));
+ errs += Integer.valueOf(m.group(2));
+ if (m.group(3) != null)
+ overflow++;
+ } else if ((m = guardPattern.matcher(line)).matches()) {
+ boolean found = false;
+ for (Pattern p: patterns) {
+ if ((m = p.matcher(line)).matches()) {
+ found = true;
+ count(p);
+ break;
+ }
+ }
+ if (!found)
+ System.err.println("Unrecognized line: " + line);
+ } else if (cssPattern.matcher(line).matches()) {
+ css++;
+ }
+ }
+ }
+
+ Map<Pattern, Integer> counts = new HashMap<>();
+ void count(Pattern p) {
+ Integer i = counts.get(p);
+ counts.put(p, (i == null) ? 1 : i + 1);
+ }
+
+ void print(String format, Object... args) {
+ System.out.println(String.format(format, args));
+ }
+
+ Pattern okPattern = Pattern.compile("No warnings or errors were found.");
+ Pattern countPattern = Pattern.compile("([0-9]+) warnings, ([0-9]+) errors were found!.*?(Not all warnings/errors were shown.)?");
+ Pattern cssPattern = Pattern.compile("You are recommended to use CSS.*");
+ Pattern guardPattern = Pattern.compile("line [0-9]+ column [0-9]+ - (Error|Warning):.*");
+
+ Pattern[] patterns = {
+ Pattern.compile(".*Error: <.*> is not recognized!"),
+ Pattern.compile(".*Error: missing quote mark for attribute value"),
+ Pattern.compile(".*Warning: <.*> anchor \".*\" already defined"),
+ Pattern.compile(".*Warning: <.*> attribute \".*\" has invalid value \".*\""),
+ Pattern.compile(".*Warning: <.*> attribute \".*\" lacks value"),
+ Pattern.compile(".*Warning: <.*> attribute \".*\" lacks value"),
+ Pattern.compile(".*Warning: <.*> attribute with missing trailing quote mark"),
+ Pattern.compile(".*Warning: <.*> dropping value \".*\" for repeated attribute \".*\""),
+ Pattern.compile(".*Warning: <.*> inserting \".*\" attribute"),
+ Pattern.compile(".*Warning: <.*> is probably intended as </.*>"),
+ Pattern.compile(".*Warning: <.*> isn't allowed in <.*> elements"),
+ Pattern.compile(".*Warning: <.*> lacks \".*\" attribute"),
+ Pattern.compile(".*Warning: <.*> missing '>' for end of tag"),
+ Pattern.compile(".*Warning: <.*> proprietary attribute \".*\""),
+ Pattern.compile(".*Warning: <.*> unexpected or duplicate quote mark"),
+ Pattern.compile(".*Warning: <a> cannot copy name attribute to id"),
+ Pattern.compile(".*Warning: <a> escaping malformed URI reference"),
+ Pattern.compile(".*Warning: <blockquote> proprietary attribute \"pre\""),
+ Pattern.compile(".*Warning: discarding unexpected <.*>"),
+ Pattern.compile(".*Warning: discarding unexpected </.*>"),
+ Pattern.compile(".*Warning: entity \".*\" doesn't end in ';'"),
+ Pattern.compile(".*Warning: inserting implicit <.*>"),
+ Pattern.compile(".*Warning: inserting missing 'title' element"),
+ Pattern.compile(".*Warning: missing <!DOCTYPE> declaration"),
+ Pattern.compile(".*Warning: missing <.*>"),
+ Pattern.compile(".*Warning: missing </.*> before <.*>"),
+ Pattern.compile(".*Warning: nested emphasis <.*>"),
+ Pattern.compile(".*Warning: plain text isn't allowed in <.*> elements"),
+ Pattern.compile(".*Warning: replacing <p> by <br>"),
+ Pattern.compile(".*Warning: replacing invalid numeric character reference .*"),
+ Pattern.compile(".*Warning: replacing unexpected .* by </.*>"),
+ Pattern.compile(".*Warning: trimming empty <.*>"),
+ Pattern.compile(".*Warning: unescaped & or unknown entity \".*\""),
+ Pattern.compile(".*Warning: unescaped & which should be written as &"),
+ Pattern.compile(".*Warning: using <br> in place of <p>")
+ };
+
+ int files;
+ int ok;
+ int warns;
+ int errs;
+ int css;
+ int overflow;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/tidy/util/tidy.sh Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# 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.
+#
+
+# Run the "tidy" program over the files in a directory.
+#
+# Usage:
+# sh tidy.sh <dir>
+#
+# The "tidy" program will be run on each HTML file in <dir>,
+# and the output placed in the corresponding location in a new
+# directory <dir>.tidy. The console output from running "tidy" will
+# be saved in a corresponding file with an additional .tidy extension.
+#
+# Non-HTML files will be copied without modification from <dir> to
+# <dir>.tidy, so that relative links within the directory tree are
+# unaffected.
+
+dir=$1
+odir=$dir.tidy
+
+( cd $dir ; find . -type f ) | \
+ while read file ; do
+ mkdir -p $odir/$(dirname $file)
+ case $file in
+ *.html )
+ cat $dir/$file | tidy 1>$odir/$file 2>$odir/$file.tidy
+ ;;
+ * ) cp $dir/$file $odir/$file
+ ;;
+ esac
+ done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoContent.java Mon Dec 17 07:47:05 2012 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.dc.no.content
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @see */
+class NoContent {
+}
+