mirror of
https://github.com/openjdk/jdk.git
synced 2026-08-02 22:25:29 +00:00
8004832: Add new doclint package
Reviewed-by: mcimadamore
This commit is contained in:
parent
c5acce4569
commit
4a3e904c6e
@ -117,7 +117,8 @@ javac.includes = \
|
||||
javax/lang/model/ \
|
||||
javax/tools/ \
|
||||
com/sun/source/ \
|
||||
com/sun/tools/javac/
|
||||
com/sun/tools/javac/ \
|
||||
com/sun/tools/doclint/
|
||||
|
||||
javac.tests = \
|
||||
tools/javac
|
||||
|
||||
@ -45,9 +45,7 @@ public abstract class DocTrees extends Trees {
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -139,6 +139,7 @@ public abstract class JavacTask implements CompilationTask {
|
||||
* @see com.sun.source.util.Trees#getTypeMirror
|
||||
*/
|
||||
public abstract TypeMirror getTypeMirror(Iterable<? extends Tree> path);
|
||||
|
||||
/**
|
||||
* Get a utility object for dealing with program elements.
|
||||
*/
|
||||
|
||||
@ -60,14 +60,20 @@ public class TreePath implements Iterable<Tree> {
|
||||
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) {
|
||||
|
||||
754
langtools/src/share/classes/com/sun/tools/doclint/Checker.java
Normal file
754
langtools/src/share/classes/com/sun/tools/doclint/Checker.java
Normal file
@ -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>
|
||||
|
||||
}
|
||||
376
langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
Normal file
376
langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
Normal file
@ -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>
|
||||
|
||||
}
|
||||
326
langtools/src/share/classes/com/sun/tools/doclint/Entity.java
Normal file
326
langtools/src/share/classes/com/sun/tools/doclint/Entity.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
166
langtools/src/share/classes/com/sun/tools/doclint/Env.java
Normal file
166
langtools/src/share/classes/com/sun/tools/doclint/Env.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
356
langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java
Normal file
356
langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java
Normal file
@ -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());
|
||||
}
|
||||
}
|
||||
348
langtools/src/share/classes/com/sun/tools/doclint/Messages.java
Normal file
348
langtools/src/share/classes/com/sun/tools/doclint/Messages.java
Normal file
@ -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>
|
||||
}
|
||||
@ -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
|
||||
@ -57,6 +57,13 @@ public class BasicJavacTask extends JavacTask {
|
||||
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)
|
||||
|
||||
@ -65,7 +65,6 @@ import com.sun.tools.javac.util.List;
|
||||
* @author Jonathan Gibbons
|
||||
*/
|
||||
public class JavacTaskImpl extends BasicJavacTask {
|
||||
private ClientCodeWrapper ccw;
|
||||
private Main compilerMain;
|
||||
private JavaCompiler compiler;
|
||||
private Locale locale;
|
||||
@ -85,7 +84,6 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
Context context,
|
||||
List<JavaFileObject> fileObjects) {
|
||||
super(null, false);
|
||||
this.ccw = ClientCodeWrapper.instance(context);
|
||||
this.compilerMain = compilerMain;
|
||||
this.args = args;
|
||||
this.classNames = classNames;
|
||||
|
||||
@ -84,6 +84,7 @@ import com.sun.tools.javac.tree.JCTree.*;
|
||||
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 class JavacTrees extends DocTrees {
|
||||
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 @@ public class JavacTrees extends DocTrees {
|
||||
} else {
|
||||
return msym;
|
||||
}
|
||||
} catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
|
||||
return null;
|
||||
} finally {
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
|
||||
@ -1675,7 +1675,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
|
||||
/** 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)
|
||||
|
||||
@ -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 @@ public class JavacTypes implements javax.lang.model.util.Types {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.DCTree.DCText;
|
||||
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 @@ public class DocCommentParser {
|
||||
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 @@ public class DocCommentParser {
|
||||
}
|
||||
|
||||
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 @@ public class DocCommentParser {
|
||||
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);
|
||||
|
||||
@ -2364,6 +2364,9 @@ compiler.err.dc.malformed.html=\
|
||||
compiler.err.dc.missing.semicolon=\
|
||||
semicolon missing
|
||||
|
||||
compiler.err.dc.no.content=\
|
||||
no content
|
||||
|
||||
compiler.err.dc.no.tag.name=\
|
||||
no tag name after '@'
|
||||
|
||||
|
||||
@ -36,6 +36,8 @@ import com.sun.tools.javac.util.JCDiagnostic;
|
||||
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 @@ public abstract class DCTree implements DocTree {
|
||||
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
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ public class DocPretty implements DocTreeVisitor<Void,Void> {
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
@ -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 @@ public class TreeInfo {
|
||||
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.
|
||||
*/
|
||||
|
||||
63
langtools/test/tools/doclint/AccessTest.java
Normal file
63
langtools/test/tools/doclint/AccessTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
20
langtools/test/tools/doclint/AccessTest.package.out
Normal file
20
langtools/test/tools/doclint/AccessTest.package.out
Normal file
@ -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
|
||||
|
||||
27
langtools/test/tools/doclint/AccessTest.private.out
Normal file
27
langtools/test/tools/doclint/AccessTest.private.out
Normal file
@ -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
|
||||
|
||||
|
||||
8
langtools/test/tools/doclint/AccessTest.protected.out
Normal file
8
langtools/test/tools/doclint/AccessTest.protected.out
Normal file
@ -0,0 +1,8 @@
|
||||
AccessTest.java:21: error: malformed HTML
|
||||
* public a < b
|
||||
^
|
||||
AccessTest.java:26: error: malformed HTML
|
||||
* protected a < b
|
||||
^
|
||||
2 errors
|
||||
|
||||
5
langtools/test/tools/doclint/AccessTest.public.out
Normal file
5
langtools/test/tools/doclint/AccessTest.public.out
Normal file
@ -0,0 +1,5 @@
|
||||
AccessTest.java:21: error: malformed HTML
|
||||
* public a < b
|
||||
^
|
||||
1 error
|
||||
|
||||
42
langtools/test/tools/doclint/AccessibilityTest.java
Normal file
42
langtools/test/tools/doclint/AccessibilityTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
13
langtools/test/tools/doclint/AccessibilityTest.out
Normal file
13
langtools/test/tools/doclint/AccessibilityTest.out
Normal file
@ -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
|
||||
135
langtools/test/tools/doclint/DocLintTester.java
Normal file
135
langtools/test/tools/doclint/DocLintTester.java
Normal file
@ -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;
|
||||
}
|
||||
10
langtools/test/tools/doclint/EmptyAuthorTest.java
Normal file
10
langtools/test/tools/doclint/EmptyAuthorTest.java
Normal file
@ -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 {
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptyAuthorTest.out
Normal file
5
langtools/test/tools/doclint/EmptyAuthorTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptyAuthorTest.java:8: warning: no description for @author
|
||||
/** @author */
|
||||
^
|
||||
1 warning
|
||||
|
||||
12
langtools/test/tools/doclint/EmptyExceptionTest.java
Normal file
12
langtools/test/tools/doclint/EmptyExceptionTest.java
Normal file
@ -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 { }
|
||||
}
|
||||
4
langtools/test/tools/doclint/EmptyExceptionTest.out
Normal file
4
langtools/test/tools/doclint/EmptyExceptionTest.out
Normal file
@ -0,0 +1,4 @@
|
||||
EmptyExceptionTest.java:10: warning: no description for @exception
|
||||
/** @exception NullPointerException */
|
||||
^
|
||||
1 warning
|
||||
12
langtools/test/tools/doclint/EmptyParamTest.java
Normal file
12
langtools/test/tools/doclint/EmptyParamTest.java
Normal file
@ -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) { }
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptyParamTest.out
Normal file
5
langtools/test/tools/doclint/EmptyParamTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptyParamTest.java:10: warning: no description for @param
|
||||
/** @param i */
|
||||
^
|
||||
1 warning
|
||||
|
||||
12
langtools/test/tools/doclint/EmptyReturnTest.java
Normal file
12
langtools/test/tools/doclint/EmptyReturnTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptyReturnTest.out
Normal file
5
langtools/test/tools/doclint/EmptyReturnTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptyReturnTest.java:10: warning: no description for @return
|
||||
/** @return */
|
||||
^
|
||||
1 warning
|
||||
|
||||
15
langtools/test/tools/doclint/EmptySerialDataTest.java
Normal file
15
langtools/test/tools/doclint/EmptySerialDataTest.java
Normal file
@ -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) { }
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptySerialDataTest.out
Normal file
5
langtools/test/tools/doclint/EmptySerialDataTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptySerialDataTest.java:13: warning: no description for @serialData
|
||||
/** @serialData */
|
||||
^
|
||||
1 warning
|
||||
|
||||
20
langtools/test/tools/doclint/EmptySerialFieldTest.java
Normal file
20
langtools/test/tools/doclint/EmptySerialFieldTest.java
Normal file
@ -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),
|
||||
};
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptySerialFieldTest.out
Normal file
5
langtools/test/tools/doclint/EmptySerialFieldTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptySerialFieldTest.java:15: warning: no description for @serialField
|
||||
* @serialField empty String
|
||||
^
|
||||
1 warning
|
||||
|
||||
12
langtools/test/tools/doclint/EmptySinceTest.java
Normal file
12
langtools/test/tools/doclint/EmptySinceTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
5
langtools/test/tools/doclint/EmptySinceTest.out
Normal file
5
langtools/test/tools/doclint/EmptySinceTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
EmptySinceTest.java:10: warning: no description for @since
|
||||
/** @since */
|
||||
^
|
||||
1 warning
|
||||
|
||||
12
langtools/test/tools/doclint/EmptyVersionTest.java
Normal file
12
langtools/test/tools/doclint/EmptyVersionTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
4
langtools/test/tools/doclint/EmptyVersionTest.out
Normal file
4
langtools/test/tools/doclint/EmptyVersionTest.out
Normal file
@ -0,0 +1,4 @@
|
||||
EmptyVersionTest.java:10: warning: no description for @version
|
||||
/** @version */
|
||||
^
|
||||
1 warning
|
||||
25
langtools/test/tools/doclint/HtmlAttrsTest.java
Normal file
25
langtools/test/tools/doclint/HtmlAttrsTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
12
langtools/test/tools/doclint/HtmlAttrsTest.out
Normal file
12
langtools/test/tools/doclint/HtmlAttrsTest.out
Normal file
@ -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
|
||||
|
||||
56
langtools/test/tools/doclint/HtmlTagsTest.java
Normal file
56
langtools/test/tools/doclint/HtmlTagsTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
38
langtools/test/tools/doclint/HtmlTagsTest.out
Normal file
38
langtools/test/tools/doclint/HtmlTagsTest.out
Normal file
@ -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
|
||||
14
langtools/test/tools/doclint/MissingCommentTest.java
Normal file
14
langtools/test/tools/doclint/MissingCommentTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
14
langtools/test/tools/doclint/MissingCommentTest.out
Normal file
14
langtools/test/tools/doclint/MissingCommentTest.out
Normal file
@ -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
|
||||
|
||||
21
langtools/test/tools/doclint/MissingParamsTest.java
Normal file
21
langtools/test/tools/doclint/MissingParamsTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
14
langtools/test/tools/doclint/MissingParamsTest.out
Normal file
14
langtools/test/tools/doclint/MissingParamsTest.out
Normal file
@ -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
|
||||
|
||||
21
langtools/test/tools/doclint/MissingReturnTest.java
Normal file
21
langtools/test/tools/doclint/MissingReturnTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
5
langtools/test/tools/doclint/MissingReturnTest.out
Normal file
5
langtools/test/tools/doclint/MissingReturnTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
MissingReturnTest.java:20: warning: no @return
|
||||
int missingReturn() { }
|
||||
^
|
||||
1 warning
|
||||
|
||||
12
langtools/test/tools/doclint/MissingThrowsTest.java
Normal file
12
langtools/test/tools/doclint/MissingThrowsTest.java
Normal file
@ -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 { }
|
||||
}
|
||||
4
langtools/test/tools/doclint/MissingThrowsTest.out
Normal file
4
langtools/test/tools/doclint/MissingThrowsTest.out
Normal file
@ -0,0 +1,4 @@
|
||||
MissingThrowsTest.java:11: warning: no @throws for java.lang.Exception
|
||||
void missingThrows() throws Exception { }
|
||||
^
|
||||
1 warning
|
||||
94
langtools/test/tools/doclint/OptionTest.java
Normal file
94
langtools/test/tools/doclint/OptionTest.java
Normal file
@ -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;
|
||||
}
|
||||
91
langtools/test/tools/doclint/OverridesTest.java
Normal file
91
langtools/test/tools/doclint/OverridesTest.java
Normal file
@ -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; }
|
||||
}
|
||||
50
langtools/test/tools/doclint/ReferenceTest.java
Normal file
50
langtools/test/tools/doclint/ReferenceTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
30
langtools/test/tools/doclint/ReferenceTest.out
Normal file
30
langtools/test/tools/doclint/ReferenceTest.out
Normal file
@ -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
|
||||
|
||||
103
langtools/test/tools/doclint/RunTest.java
Normal file
103
langtools/test/tools/doclint/RunTest.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
langtools/test/tools/doclint/SyntaxTest.java
Normal file
15
langtools/test/tools/doclint/SyntaxTest.java
Normal file
@ -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() { }
|
||||
}
|
||||
|
||||
5
langtools/test/tools/doclint/SyntaxTest.out
Normal file
5
langtools/test/tools/doclint/SyntaxTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
SyntaxTest.java:11: error: malformed HTML
|
||||
* a < b
|
||||
^
|
||||
1 error
|
||||
|
||||
48
langtools/test/tools/doclint/SyntheticTest.java
Normal file
48
langtools/test/tools/doclint/SyntheticTest.java
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
110
langtools/test/tools/doclint/ValidTest.java
Normal file
110
langtools/test/tools/doclint/ValidTest.java
Normal file
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
15
langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.java
Normal file
15
langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.java
Normal file
@ -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 { }
|
||||
@ -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
|
||||
14
langtools/test/tools/doclint/tidy/BadEnd.java
Normal file
14
langtools/test/tools/doclint/tidy/BadEnd.java
Normal file
@ -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 { }
|
||||
17
langtools/test/tools/doclint/tidy/BadEnd.out
Normal file
17
langtools/test/tools/doclint/tidy/BadEnd.out
Normal file
@ -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
|
||||
14
langtools/test/tools/doclint/tidy/InsertImplicit.java
Normal file
14
langtools/test/tools/doclint/tidy/InsertImplicit.java
Normal file
@ -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 { }
|
||||
7
langtools/test/tools/doclint/tidy/InsertImplicit.out
Normal file
7
langtools/test/tools/doclint/tidy/InsertImplicit.out
Normal file
@ -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
|
||||
20
langtools/test/tools/doclint/tidy/InvalidEntity.java
Normal file
20
langtools/test/tools/doclint/tidy/InvalidEntity.java
Normal file
@ -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 { }
|
||||
10
langtools/test/tools/doclint/tidy/InvalidEntity.out
Normal file
10
langtools/test/tools/doclint/tidy/InvalidEntity.out
Normal file
@ -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
|
||||
16
langtools/test/tools/doclint/tidy/InvalidName.java
Normal file
16
langtools/test/tools/doclint/tidy/InvalidName.java
Normal file
@ -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 { }
|
||||
4
langtools/test/tools/doclint/tidy/InvalidName.out
Normal file
4
langtools/test/tools/doclint/tidy/InvalidName.out
Normal file
@ -0,0 +1,4 @@
|
||||
InvalidName.java:14: error: invalid name for anchor: "foo()"
|
||||
* <a name="foo()">invalid</a>
|
||||
^
|
||||
1 error
|
||||
13
langtools/test/tools/doclint/tidy/InvalidTag.java
Normal file
13
langtools/test/tools/doclint/tidy/InvalidTag.java
Normal file
@ -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 { }
|
||||
10
langtools/test/tools/doclint/tidy/InvalidTag.out
Normal file
10
langtools/test/tools/doclint/tidy/InvalidTag.out
Normal file
@ -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
|
||||
19
langtools/test/tools/doclint/tidy/InvalidURI.java
Normal file
19
langtools/test/tools/doclint/tidy/InvalidURI.java
Normal file
@ -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 { }
|
||||
13
langtools/test/tools/doclint/tidy/InvalidURI.out
Normal file
13
langtools/test/tools/doclint/tidy/InvalidURI.out
Normal file
@ -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
|
||||
14
langtools/test/tools/doclint/tidy/MissingGT.java
Normal file
14
langtools/test/tools/doclint/tidy/MissingGT.java
Normal file
@ -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 { }
|
||||
4
langtools/test/tools/doclint/tidy/MissingGT.out
Normal file
4
langtools/test/tools/doclint/tidy/MissingGT.out
Normal file
@ -0,0 +1,4 @@
|
||||
MissingGT.java:11: error: malformed HTML
|
||||
* <img src="image.gif"
|
||||
^
|
||||
1 error
|
||||
15
langtools/test/tools/doclint/tidy/MissingTag.java
Normal file
15
langtools/test/tools/doclint/tidy/MissingTag.java
Normal file
@ -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 { }
|
||||
7
langtools/test/tools/doclint/tidy/MissingTag.out
Normal file
7
langtools/test/tools/doclint/tidy/MissingTag.out
Normal file
@ -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
|
||||
14
langtools/test/tools/doclint/tidy/NestedTag.java
Normal file
14
langtools/test/tools/doclint/tidy/NestedTag.java
Normal file
@ -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 { }
|
||||
7
langtools/test/tools/doclint/tidy/NestedTag.out
Normal file
7
langtools/test/tools/doclint/tidy/NestedTag.out
Normal file
@ -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
|
||||
18
langtools/test/tools/doclint/tidy/ParaInPre.java
Normal file
18
langtools/test/tools/doclint/tidy/ParaInPre.java
Normal file
@ -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 { }
|
||||
4
langtools/test/tools/doclint/tidy/ParaInPre.out
Normal file
4
langtools/test/tools/doclint/tidy/ParaInPre.out
Normal file
@ -0,0 +1,4 @@
|
||||
ParaInPre.java:14: warning: unexpected use of <p> inside <pre> element
|
||||
* <p>
|
||||
^
|
||||
1 warning
|
||||
21
langtools/test/tools/doclint/tidy/README.txt
Normal file
21
langtools/test/tools/doclint/tidy/README.txt
Normal file
@ -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/.
|
||||
13
langtools/test/tools/doclint/tidy/RepeatedAttr.java
Normal file
13
langtools/test/tools/doclint/tidy/RepeatedAttr.java
Normal file
@ -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 { }
|
||||
4
langtools/test/tools/doclint/tidy/RepeatedAttr.out
Normal file
4
langtools/test/tools/doclint/tidy/RepeatedAttr.out
Normal file
@ -0,0 +1,4 @@
|
||||
RepeatedAttr.java:11: error: repeated attribute: alt
|
||||
* <img src="image.gif" alt alt="summary">
|
||||
^
|
||||
1 error
|
||||
24
langtools/test/tools/doclint/tidy/TextNotAllowed.java
Normal file
24
langtools/test/tools/doclint/tidy/TextNotAllowed.java
Normal file
@ -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 { }
|
||||
19
langtools/test/tools/doclint/tidy/TextNotAllowed.out
Normal file
19
langtools/test/tools/doclint/tidy/TextNotAllowed.out
Normal file
@ -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
|
||||
27
langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java
Normal file
27
langtools/test/tools/doclint/tidy/TrimmingEmptyTag.java
Normal file
@ -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 { }
|
||||
46
langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out
Normal file
46
langtools/test/tools/doclint/tidy/TrimmingEmptyTag.out
Normal file
@ -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
|
||||
@ -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 { }
|
||||
@ -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
|
||||
|
||||
182
langtools/test/tools/doclint/tidy/util/Main.java
Normal file
182
langtools/test/tools/doclint/tidy/util/Main.java
Normal file
@ -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;
|
||||
}
|
||||
|
||||
52
langtools/test/tools/doclint/tidy/util/tidy.sh
Normal file
52
langtools/test/tools/doclint/tidy/util/tidy.sh
Normal file
@ -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
|
||||
33
langtools/test/tools/javac/diags/examples/NoContent.java
Normal file
33
langtools/test/tools/javac/diags/examples/NoContent.java
Normal file
@ -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 {
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user