29 import java.io.StringWriter; |
29 import java.io.StringWriter; |
30 import java.net.URI; |
30 import java.net.URI; |
31 import java.net.URISyntaxException; |
31 import java.net.URISyntaxException; |
32 import java.util.Deque; |
32 import java.util.Deque; |
33 import java.util.EnumSet; |
33 import java.util.EnumSet; |
|
34 import java.util.HashMap; |
34 import java.util.HashSet; |
35 import java.util.HashSet; |
35 import java.util.LinkedList; |
36 import java.util.LinkedList; |
36 import java.util.List; |
37 import java.util.List; |
|
38 import java.util.Map; |
37 import java.util.Set; |
39 import java.util.Set; |
38 import java.util.regex.Matcher; |
40 import java.util.regex.Matcher; |
39 import java.util.regex.Pattern; |
41 import java.util.regex.Pattern; |
40 |
42 |
41 import javax.lang.model.element.Element; |
43 import javax.lang.model.element.Element; |
43 import javax.lang.model.element.ExecutableElement; |
45 import javax.lang.model.element.ExecutableElement; |
44 import javax.lang.model.element.Name; |
46 import javax.lang.model.element.Name; |
45 import javax.lang.model.type.TypeKind; |
47 import javax.lang.model.type.TypeKind; |
46 import javax.lang.model.type.TypeMirror; |
48 import javax.lang.model.type.TypeMirror; |
47 import javax.tools.Diagnostic.Kind; |
49 import javax.tools.Diagnostic.Kind; |
|
50 import javax.tools.JavaFileObject; |
48 |
51 |
49 import com.sun.source.doctree.AttributeTree; |
52 import com.sun.source.doctree.AttributeTree; |
50 import com.sun.source.doctree.AuthorTree; |
53 import com.sun.source.doctree.AuthorTree; |
51 import com.sun.source.doctree.DocCommentTree; |
54 import com.sun.source.doctree.DocCommentTree; |
52 import com.sun.source.doctree.DocRootTree; |
55 import com.sun.source.doctree.DocRootTree; |
86 * or deletion without notice.</b></p> |
89 * or deletion without notice.</b></p> |
87 */ |
90 */ |
88 public class Checker extends DocTreePathScanner<Void, Void> { |
91 public class Checker extends DocTreePathScanner<Void, Void> { |
89 final Env env; |
92 final Env env; |
90 |
93 |
91 Set<Element> foundParams = new HashSet<Element>(); |
94 Set<Element> foundParams = new HashSet<>(); |
92 Set<TypeMirror> foundThrows = new HashSet<TypeMirror>(); |
95 Set<TypeMirror> foundThrows = new HashSet<>(); |
93 Set<String> foundAnchors = new HashSet<String>(); |
96 Map<JavaFileObject, Set<String>> foundAnchors = new HashMap<>(); |
94 boolean foundInheritDoc = false; |
97 boolean foundInheritDoc = false; |
95 boolean foundReturn = false; |
98 boolean foundReturn = false; |
96 |
99 |
97 public enum Flag { |
100 public enum Flag { |
98 TABLE_HAS_CAPTION, |
101 TABLE_HAS_CAPTION, |
127 // <editor-fold defaultstate="collapsed" desc="Top level"> |
130 // <editor-fold defaultstate="collapsed" desc="Top level"> |
128 |
131 |
129 Checker(Env env) { |
132 Checker(Env env) { |
130 env.getClass(); |
133 env.getClass(); |
131 this.env = env; |
134 this.env = env; |
132 tagStack = new LinkedList<TagStackItem>(); |
135 tagStack = new LinkedList<>(); |
133 implicitHeaderLevel = env.implicitHeaderLevel; |
136 implicitHeaderLevel = env.implicitHeaderLevel; |
134 } |
137 } |
135 |
138 |
136 public Void scan(DocCommentTree tree, TreePath p) { |
139 public Void scan(DocCommentTree tree, TreePath p) { |
137 env.setCurrent(p, tree); |
140 env.setCurrent(p, tree); |
506 env.messages.error(HTML, tree, "dc.anchor.value.missing"); |
509 env.messages.error(HTML, tree, "dc.anchor.value.missing"); |
507 } else { |
510 } else { |
508 if (!validName.matcher(value).matches()) { |
511 if (!validName.matcher(value).matches()) { |
509 env.messages.error(HTML, tree, "dc.invalid.anchor", value); |
512 env.messages.error(HTML, tree, "dc.invalid.anchor", value); |
510 } |
513 } |
511 if (!foundAnchors.add(value)) { |
514 if (!checkAnchor(value)) { |
512 env.messages.error(HTML, tree, "dc.anchor.already.defined", value); |
515 env.messages.error(HTML, tree, "dc.anchor.already.defined", value); |
513 } |
516 } |
514 } |
517 } |
515 break; |
518 break; |
516 |
519 |
549 // TODO: basic check on value |
552 // TODO: basic check on value |
550 |
553 |
551 return super.visitAttribute(tree, ignore); |
554 return super.visitAttribute(tree, ignore); |
552 } |
555 } |
553 |
556 |
|
557 private boolean checkAnchor(String name) { |
|
558 JavaFileObject fo = env.currPath.getCompilationUnit().getSourceFile(); |
|
559 Set<String> set = foundAnchors.get(fo); |
|
560 if (set == null) |
|
561 foundAnchors.put(fo, set = new HashSet<>()); |
|
562 return set.add(name); |
|
563 } |
|
564 |
554 // http://www.w3.org/TR/html401/types.html#type-name |
565 // http://www.w3.org/TR/html401/types.html#type-name |
555 private static final Pattern validName = Pattern.compile("[A-Za-z][A-Za-z0-9-_:.]*"); |
566 private static final Pattern validName = Pattern.compile("[A-Za-z][A-Za-z0-9-_:.]*"); |
556 |
567 |
557 private static final Pattern validNumber = Pattern.compile("-?[0-9]+"); |
568 private static final Pattern validNumber = Pattern.compile("-?[0-9]+"); |
558 |
569 |