1 /* |
1 /* |
2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
59 import com.sun.source.doctree.EntityTree; |
59 import com.sun.source.doctree.EntityTree; |
60 import com.sun.source.doctree.ErroneousTree; |
60 import com.sun.source.doctree.ErroneousTree; |
61 import com.sun.source.doctree.IdentifierTree; |
61 import com.sun.source.doctree.IdentifierTree; |
62 import com.sun.source.doctree.IndexTree; |
62 import com.sun.source.doctree.IndexTree; |
63 import com.sun.source.doctree.InheritDocTree; |
63 import com.sun.source.doctree.InheritDocTree; |
64 import com.sun.source.doctree.InlineTagTree; |
|
65 import com.sun.source.doctree.LinkTree; |
64 import com.sun.source.doctree.LinkTree; |
66 import com.sun.source.doctree.LiteralTree; |
65 import com.sun.source.doctree.LiteralTree; |
67 import com.sun.source.doctree.ParamTree; |
66 import com.sun.source.doctree.ParamTree; |
68 import com.sun.source.doctree.ProvidesTree; |
67 import com.sun.source.doctree.ProvidesTree; |
69 import com.sun.source.doctree.ReferenceTree; |
68 import com.sun.source.doctree.ReferenceTree; |
138 return String.valueOf(tag); |
137 return String.valueOf(tag); |
139 } |
138 } |
140 } |
139 } |
141 |
140 |
142 private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well |
141 private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well |
143 private HtmlTag currHeaderTag; |
142 private HtmlTag currHeadingTag; |
144 |
143 |
145 private final int implicitHeaderLevel; |
144 private int implicitHeadingRank; |
146 |
145 |
147 // <editor-fold defaultstate="collapsed" desc="Top level"> |
146 // <editor-fold defaultstate="collapsed" desc="Top level"> |
148 |
147 |
149 Checker(Env env) { |
148 Checker(Env env) { |
150 this.env = Assert.checkNonNull(env); |
149 this.env = Assert.checkNonNull(env); |
151 tagStack = new LinkedList<>(); |
150 tagStack = new LinkedList<>(); |
152 implicitHeaderLevel = env.implicitHeaderLevel; |
|
153 } |
151 } |
154 |
152 |
155 public Void scan(DocCommentTree tree, TreePath p) { |
153 public Void scan(DocCommentTree tree, TreePath p) { |
156 env.initTypes(); |
154 env.initTypes(); |
157 env.setCurrent(p, tree); |
155 env.setCurrent(p, tree); |
186 return null; |
184 return null; |
187 } |
185 } |
188 } |
186 } |
189 |
187 |
190 tagStack.clear(); |
188 tagStack.clear(); |
191 currHeaderTag = null; |
189 currHeadingTag = null; |
192 |
190 |
193 foundParams.clear(); |
191 foundParams.clear(); |
194 foundThrows.clear(); |
192 foundThrows.clear(); |
195 foundInheritDoc = false; |
193 foundInheritDoc = false; |
196 foundReturn = false; |
194 foundReturn = false; |
197 hasNonWhitespaceText = false; |
195 hasNonWhitespaceText = false; |
|
196 |
|
197 switch (p.getLeaf().getKind()) { |
|
198 // the following are for declarations that have their own top-level page, |
|
199 // and so the doc comment comes after the <h1> page title. |
|
200 case MODULE: |
|
201 case PACKAGE: |
|
202 case CLASS: |
|
203 case INTERFACE: |
|
204 case ENUM: |
|
205 case ANNOTATION_TYPE: |
|
206 implicitHeadingRank = 1; |
|
207 break; |
|
208 |
|
209 // this is for html files |
|
210 // ... if it is a legacy package.html, the doc comment comes after the <h1> page title |
|
211 // ... otherwise, (e.g. overview file and doc-files/*.html files) no additional headings are inserted |
|
212 case COMPILATION_UNIT: |
|
213 implicitHeadingRank = fo.isNameCompatible("package", JavaFileObject.Kind.HTML) ? 1 : 0; |
|
214 break; |
|
215 |
|
216 // the following are for member declarations, which appear in the page |
|
217 // for the enclosing type, and so appear after the <h2> "Members" |
|
218 // aggregate heading and the specific <h3> "Member signature" heading. |
|
219 case METHOD: |
|
220 case VARIABLE: |
|
221 implicitHeadingRank = 3; |
|
222 break; |
|
223 |
|
224 default: |
|
225 Assert.error("unexpected tree kind: " + p.getLeaf().getKind() + " " + fo); |
|
226 } |
198 |
227 |
199 scan(new DocTreePath(p, tree), null); |
228 scan(new DocTreePath(p, tree), null); |
200 |
229 |
201 if (!isOverridingMethod) { |
230 if (!isOverridingMethod) { |
202 switch (env.currElement.getKind()) { |
231 switch (env.currElement.getKind()) { |
326 markEnclosingTag(Flag.HAS_ELEMENT); |
355 markEnclosingTag(Flag.HAS_ELEMENT); |
327 checkStructure(tree, t); |
356 checkStructure(tree, t); |
328 |
357 |
329 // tag specific checks |
358 // tag specific checks |
330 switch (t) { |
359 switch (t) { |
331 // check for out of sequence headers, such as <h1>...</h1> <h3>...</h3> |
360 // check for out of sequence headings, such as <h1>...</h1> <h3>...</h3> |
332 case H1: case H2: case H3: case H4: case H5: case H6: |
361 case H1: case H2: case H3: case H4: case H5: case H6: |
333 checkHeader(tree, t); |
362 checkHeading(tree, t); |
334 break; |
363 break; |
335 } |
364 } |
336 |
365 |
337 if (t.flags.contains(HtmlTag.Flag.NO_NEST)) { |
366 if (t.flags.contains(HtmlTag.Flag.NO_NEST)) { |
338 for (TagStackItem i: tagStack) { |
367 for (TagStackItem i: tagStack) { |
444 } |
473 } |
445 |
474 |
446 env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName); |
475 env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName); |
447 } |
476 } |
448 |
477 |
449 private void checkHeader(StartElementTree tree, HtmlTag tag) { |
478 private void checkHeading(StartElementTree tree, HtmlTag tag) { |
450 // verify the new tag |
479 // verify the new tag |
451 if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) { |
480 if (getHeadingRank(tag) > getHeadingRank(currHeadingTag) + 1) { |
452 if (currHeaderTag == null) { |
481 if (currHeadingTag == null) { |
453 env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.1", tag); |
482 env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.1", |
|
483 tag, implicitHeadingRank); |
454 } else { |
484 } else { |
455 env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.2", |
485 env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.2", |
456 tag, currHeaderTag); |
486 tag, currHeadingTag); |
457 } |
487 } |
458 } |
488 } else if (getHeadingRank(tag) <= implicitHeadingRank) { |
459 |
489 env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.3", |
460 currHeaderTag = tag; |
490 tag, implicitHeadingRank); |
461 } |
491 } |
462 |
492 |
463 private int getHeaderLevel(HtmlTag tag) { |
493 currHeadingTag = tag; |
|
494 } |
|
495 |
|
496 private int getHeadingRank(HtmlTag tag) { |
464 if (tag == null) |
497 if (tag == null) |
465 return implicitHeaderLevel; |
498 return implicitHeadingRank; |
466 switch (tag) { |
499 switch (tag) { |
467 case H1: return 1; |
500 case H1: return 1; |
468 case H2: return 2; |
501 case H2: return 2; |
469 case H3: return 3; |
502 case H3: return 3; |
470 case H4: return 4; |
503 case H4: return 4; |
664 case INVALID: |
697 case INVALID: |
665 env.messages.error(HTML, tree, "dc.attr.unknown", name); |
698 env.messages.error(HTML, tree, "dc.attr.unknown", name); |
666 break; |
699 break; |
667 |
700 |
668 case OBSOLETE: |
701 case OBSOLETE: |
669 env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name); |
702 env.messages.warning(HTML, tree, "dc.attr.obsolete", name); |
670 break; |
703 break; |
671 |
704 |
672 case USE_CSS: |
705 case USE_CSS: |
673 env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name); |
706 env.messages.warning(HTML, tree, "dc.attr.obsolete.use.css", name); |
674 break; |
707 break; |
675 |
708 |
676 case HTML5: |
709 case HTML5: |
677 env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name); |
710 env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name); |
678 break; |
711 break; |