Wed, 14 Nov 2012 17:23:10 -0800
7021614: extend com.sun.source API to support parsing javadoc comments
Reviewed-by: ksrini, strarup
1 /*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.tree;
29 import javax.tools.Diagnostic;
31 import com.sun.source.doctree.*;
32 import com.sun.tools.javac.parser.Tokens.Comment;
33 import com.sun.tools.javac.util.Assert;
34 import com.sun.tools.javac.util.DiagnosticSource;
35 import com.sun.tools.javac.util.JCDiagnostic;
36 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
37 import com.sun.tools.javac.util.List;
38 import com.sun.tools.javac.util.Name;
39 import javax.tools.JavaFileObject;
41 /**
42 * <p><b>This is NOT part of any supported API.
43 * If you write code that depends on this, you do so at your own risk.
44 * This code and its internal interfaces are subject to change or
45 * deletion without notice.</b>
46 */
47 public abstract class DCTree implements DocTree {
49 /**
50 * The position in the comment string.
51 * Use {@link #getSourcePosition getSourcePosition} to convert
52 * it to a position in the source file.
53 *
54 * TODO: why not simply translate all these values into
55 * source file positions? Is it useful to have string-offset
56 * positions as well?
57 */
58 public int pos;
60 public long getSourcePosition(DCDocComment dc) {
61 return dc.comment.getSourcePos(pos);
62 }
64 public JCDiagnostic.DiagnosticPosition pos(DCDocComment dc) {
65 return new SimpleDiagnosticPosition(dc.comment.getSourcePos(pos));
66 }
68 public static class DCDocComment extends DCTree implements DocCommentTree {
69 final Comment comment; // required for the implicit source pos table
71 public final List<DCTree> firstSentence;
72 public final List<DCTree> body;
73 public final List<DCTree> tags;
75 public DCDocComment(Comment comment,
76 List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
77 this.comment = comment;
78 this.firstSentence = firstSentence;
79 this.body = body;
80 this.tags = tags;
81 }
83 public Kind getKind() {
84 return Kind.DOC_COMMENT;
85 }
87 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
88 return v.visitDocComment(this, d);
89 }
91 public List<? extends DocTree> getFirstSentence() {
92 return firstSentence;
93 }
95 public List<? extends DocTree> getBody() {
96 return body;
97 }
99 public List<? extends DocTree> getBlockTags() {
100 return tags;
101 }
103 }
105 public static abstract class DCBlockTag extends DCTree implements InlineTagTree {
106 public String getTagName() {
107 return getKind().tagName;
108 }
109 }
111 public static abstract class DCInlineTag extends DCTree implements InlineTagTree {
112 public String getTagName() {
113 return getKind().tagName;
114 }
115 }
117 public static class DCAttribute extends DCTree implements AttributeTree {
118 public final Name name;
119 public final ValueKind vkind;
120 public final List<DCTree> value;
122 DCAttribute(Name name, ValueKind vkind, List<DCTree> value) {
123 Assert.check((vkind == ValueKind.EMPTY) ? (value == null) : (value != null));
124 this.name = name;
125 this.vkind = vkind;
126 this.value = value;
127 }
129 @Override
130 public Kind getKind() {
131 return Kind.ATTRIBUTE;
132 }
134 @Override
135 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
136 return v.visitAttribute(this, d);
137 }
139 @Override
140 public Name getName() {
141 return name;
142 }
144 @Override
145 public ValueKind getValueKind() {
146 return vkind;
147 }
149 @Override
150 public List<DCTree> getValue() {
151 return value;
152 }
153 }
155 public static class DCAuthor extends DCInlineTag implements AuthorTree {
156 public final List<DCTree> name;
158 DCAuthor(List<DCTree> name) {
159 this.name = name;
160 }
162 @Override
163 public Kind getKind() {
164 return Kind.AUTHOR;
165 }
167 @Override
168 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
169 return v.visitAuthor(this, d);
170 }
172 @Override
173 public List<? extends DocTree> getName() {
174 return name;
175 }
176 }
178 public static class DCComment extends DCTree implements CommentTree {
179 public final String body;
181 DCComment(String body) {
182 this.body = body;
183 }
185 @Override
186 public Kind getKind() {
187 return Kind.COMMENT;
188 }
190 @Override
191 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
192 return v.visitComment(this, d);
193 }
195 @Override
196 public String getBody() {
197 return body;
198 }
199 }
201 public static class DCDeprecated extends DCBlockTag implements DeprecatedTree {
202 public final List<DCTree> body;
204 DCDeprecated(List<DCTree> body) {
205 this.body = body;
206 }
208 @Override
209 public Kind getKind() {
210 return Kind.DEPRECATED;
211 }
213 @Override
214 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
215 return v.visitDeprecated(this, d);
216 }
218 @Override
219 public List<? extends DocTree> getBody() {
220 return body;
221 }
222 }
224 public static class DCDocRoot extends DCInlineTag implements DocRootTree {
226 @Override
227 public Kind getKind() {
228 return Kind.DOC_ROOT;
229 }
231 @Override
232 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
233 return v.visitDocRoot(this, d);
234 }
235 }
237 public static class DCEndElement extends DCTree implements EndElementTree {
238 public final Name name;
240 DCEndElement(Name name) {
241 this.name = name;
242 }
244 @Override
245 public Kind getKind() {
246 return Kind.END_ELEMENT;
247 }
249 @Override
250 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
251 return v.visitEndElement(this, d);
252 }
254 @Override
255 public Name getName() {
256 return name;
257 }
258 }
260 public static class DCEntity extends DCTree implements EntityTree {
261 public final Name name;
263 DCEntity(Name name) {
264 this.name = name;
265 }
267 @Override
268 public Kind getKind() {
269 return Kind.ENTITY;
270 }
272 @Override
273 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
274 return v.visitEntity(this, d);
275 }
277 @Override
278 public Name getName() {
279 return name;
280 }
281 }
283 public static class DCErroneous extends DCTree implements ErroneousTree, JCDiagnostic.DiagnosticPosition {
284 public final String body;
285 public final JCDiagnostic diag;
287 DCErroneous(String body, JCDiagnostic.Factory diags, DiagnosticSource diagSource, String code, Object... args) {
288 this.body = body;
289 this.diag = diags.error(diagSource, this, code, args);
290 }
292 @Override
293 public Kind getKind() {
294 return Kind.ERRONEOUS;
295 }
297 @Override
298 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
299 return v.visitErroneous(this, d);
300 }
302 @Override
303 public String getBody() {
304 return body;
305 }
307 @Override
308 public Diagnostic<JavaFileObject> getDiagnostic() {
309 return diag;
310 }
312 @Override
313 public JCTree getTree() {
314 return null;
315 }
317 @Override
318 public int getStartPosition() {
319 return pos;
320 }
322 @Override
323 public int getPreferredPosition() {
324 return pos + body.length() - 1;
325 }
327 @Override
328 public int getEndPosition(EndPosTable endPosTable) {
329 return pos + body.length();
330 }
331 }
333 public static class DCIdentifier extends DCTree implements IdentifierTree {
334 public final Name name;
336 DCIdentifier(Name name) {
337 this.name = name;
338 }
340 @Override
341 public Kind getKind() {
342 return Kind.IDENTIFIER;
343 }
345 @Override
346 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
347 return v.visitIdentifier(this, d);
348 }
350 @Override
351 public Name getName() {
352 return name;
353 }
354 }
356 public static class DCInheritDoc extends DCInlineTag implements InheritDocTree {
357 @Override
358 public Kind getKind() {
359 return Kind.INHERIT_DOC;
360 }
362 @Override
363 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
364 return v.visitInheritDoc(this, d);
365 }
366 }
368 public static class DCLink extends DCInlineTag implements LinkTree {
369 public final Kind kind;
370 public final DCReference ref;
371 public final List<DCTree> label;
373 DCLink(Kind kind, DCReference ref, List<DCTree> label) {
374 Assert.check(kind == Kind.LINK || kind == Kind.LINK_PLAIN);
375 this.kind = kind;
376 this.ref = ref;
377 this.label = label;
378 }
380 @Override
381 public Kind getKind() {
382 return kind;
383 }
385 @Override
386 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
387 return v.visitLink(this, d);
388 }
390 @Override
391 public ReferenceTree getReference() {
392 return ref;
393 }
395 @Override
396 public List<? extends DocTree> getLabel() {
397 return label;
398 }
399 }
401 public static class DCLiteral extends DCInlineTag implements LiteralTree {
402 public final Kind kind;
403 public final DCText body;
405 DCLiteral(Kind kind, DCText body) {
406 Assert.check(kind == Kind.CODE || kind == Kind.LITERAL);
407 this.kind = kind;
408 this.body = body;
409 }
411 @Override
412 public Kind getKind() {
413 return kind;
414 }
416 @Override
417 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
418 return v.visitLiteral(this, d);
419 }
421 @Override
422 public DCText getBody() {
423 return body;
424 }
425 }
427 public static class DCParam extends DCBlockTag implements ParamTree {
428 public final boolean isTypeParameter;
429 public final DCIdentifier name;
430 public final List<DCTree> description;
432 DCParam(boolean isTypeParameter, DCIdentifier name, List<DCTree> description) {
433 this.isTypeParameter = isTypeParameter;
434 this.name = name;
435 this.description = description;
436 }
438 @Override
439 public Kind getKind() {
440 return Kind.PARAM;
441 }
443 @Override
444 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
445 return v.visitParam(this, d);
446 }
448 @Override
449 public boolean isTypeParameter() {
450 return isTypeParameter;
451 }
453 @Override
454 public IdentifierTree getName() {
455 return name;
456 }
458 @Override
459 public List<? extends DocTree> getDescription() {
460 return description;
461 }
462 }
464 public static class DCReference extends DCTree implements ReferenceTree {
465 public final String signature;
467 // The following are not directly exposed through ReferenceTree
468 // use DocTrees.getElement(TreePath,ReferenceTree)
469 public final JCTree qualifierExpression;
470 public final Name memberName;
471 public final List<JCTree> paramTypes;
474 DCReference(String signature, JCTree qualExpr, Name member, List<JCTree> paramTypes) {
475 this.signature = signature;
476 qualifierExpression = qualExpr;
477 memberName = member;
478 this.paramTypes = paramTypes;
479 }
481 @Override
482 public Kind getKind() {
483 return Kind.REFERENCE;
484 }
486 @Override
487 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
488 return v.visitReference(this, d);
489 }
491 @Override
492 public String getSignature() {
493 return signature;
494 }
495 }
497 public static class DCReturn extends DCBlockTag implements ReturnTree {
498 public final List<DCTree> description;
500 DCReturn(List<DCTree> description) {
501 this.description = description;
502 }
504 @Override
505 public Kind getKind() {
506 return Kind.RETURN;
507 }
509 @Override
510 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
511 return v.visitReturn(this, d);
512 }
514 @Override
515 public List<? extends DocTree> getDescription() {
516 return description;
517 }
518 }
520 public static class DCSee extends DCBlockTag implements SeeTree {
521 public final List<DCTree> reference;
523 DCSee(List<DCTree> reference) {
524 this.reference = reference;
525 }
527 @Override
528 public Kind getKind() {
529 return Kind.SEE;
530 }
532 @Override
533 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
534 return v.visitSee(this, d);
535 }
537 @Override
538 public List<? extends DocTree> getReference() {
539 return reference;
540 }
541 }
543 public static class DCSerial extends DCBlockTag implements SerialTree {
544 public final List<DCTree> description;
546 DCSerial(List<DCTree> description) {
547 this.description = description;
548 }
550 @Override
551 public Kind getKind() {
552 return Kind.SERIAL;
553 }
555 @Override
556 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
557 return v.visitSerial(this, d);
558 }
560 @Override
561 public List<? extends DocTree> getDescription() {
562 return description;
563 }
564 }
566 public static class DCSerialData extends DCBlockTag implements SerialDataTree {
567 public final List<DCTree> description;
569 DCSerialData(List<DCTree> description) {
570 this.description = description;
571 }
573 @Override
574 public Kind getKind() {
575 return Kind.SERIAL_DATA;
576 }
578 @Override
579 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
580 return v.visitSerialData(this, d);
581 }
583 @Override
584 public List<? extends DocTree> getDescription() {
585 return description;
586 }
587 }
589 public static class DCSerialField extends DCBlockTag implements SerialFieldTree {
590 public final DCIdentifier name;
591 public final DCReference type;
592 public final List<DCTree> description;
594 DCSerialField(DCIdentifier name, DCReference type, List<DCTree> description) {
595 this.description = description;
596 this.name = name;
597 this.type = type;
598 }
600 @Override
601 public Kind getKind() {
602 return Kind.SERIAL_FIELD;
603 }
605 @Override
606 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
607 return v.visitSerialField(this, d);
608 }
610 @Override
611 public List<? extends DocTree> getDescription() {
612 return description;
613 }
615 @Override
616 public IdentifierTree getName() {
617 return name;
618 }
620 @Override
621 public ReferenceTree getType() {
622 return type;
623 }
624 }
626 public static class DCSince extends DCInlineTag implements SinceTree {
627 public final List<DCTree> body;
629 DCSince(List<DCTree> body) {
630 this.body = body;
631 }
633 @Override
634 public Kind getKind() {
635 return Kind.SINCE;
636 }
638 @Override
639 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
640 return v.visitSince(this, d);
641 }
643 @Override
644 public List<? extends DocTree> getBody() {
645 return body;
646 }
647 }
649 public static class DCStartElement extends DCTree implements StartElementTree {
650 public final Name name;
651 public final List<DCTree> attrs;
652 public final boolean selfClosing;
654 DCStartElement(Name name, List<DCTree> attrs, boolean selfClosing) {
655 this.name = name;
656 this.attrs = attrs;
657 this.selfClosing = selfClosing;
658 }
660 @Override
661 public Kind getKind() {
662 return Kind.START_ELEMENT;
663 }
665 @Override
666 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
667 return v.visitStartElement(this, d);
668 }
670 @Override
671 public Name getName() {
672 return name;
673 }
675 @Override
676 public List<? extends DocTree> getAttributes() {
677 return attrs;
678 }
680 @Override
681 public boolean isSelfClosing() {
682 return selfClosing;
683 }
684 }
686 public static class DCText extends DCTree implements TextTree {
687 public final String text;
689 DCText(String text) {
690 this.text = text;
691 }
693 @Override
694 public Kind getKind() {
695 return Kind.TEXT;
696 }
698 @Override
699 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
700 return v.visitText(this, d);
701 }
703 @Override
704 public String getBody() {
705 return text;
706 }
707 }
709 public static class DCThrows extends DCBlockTag implements ThrowsTree {
710 public final Kind kind;
711 public final DCReference name;
712 public final List<DCTree> description;
714 DCThrows(Kind kind, DCReference name, List<DCTree> description) {
715 Assert.check(kind == Kind.EXCEPTION || kind == Kind.THROWS);
716 this.kind = kind;
717 this.name = name;
718 this.description = description;
719 }
721 @Override
722 public Kind getKind() {
723 return kind;
724 }
726 @Override
727 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
728 return v.visitThrows(this, d);
729 }
731 @Override
732 public ReferenceTree getExceptionName() {
733 return name;
734 }
736 @Override
737 public List<? extends DocTree> getDescription() {
738 return description;
739 }
740 }
742 public static class DCUnknownBlockTag extends DCBlockTag implements UnknownBlockTagTree {
743 public final Name name;
744 public final List<DCTree> content;
746 DCUnknownBlockTag(Name name, List<DCTree> content) {
747 this.name = name;
748 this.content = content;
749 }
751 @Override
752 public Kind getKind() {
753 return Kind.UNKNOWN_BLOCK_TAG;
754 }
756 @Override
757 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
758 return v.visitUnknownBlockTag(this, d);
759 }
761 @Override
762 public String getTagName() {
763 return name.toString();
764 }
766 @Override
767 public List<? extends DocTree> getContent() {
768 return content;
769 }
770 }
772 public static class DCUnknownInlineTag extends DCInlineTag implements UnknownInlineTagTree {
773 public final Name name;
774 public final List<DCTree> content;
776 DCUnknownInlineTag(Name name, List<DCTree> content) {
777 this.name = name;
778 this.content = content;
779 }
781 @Override
782 public Kind getKind() {
783 return Kind.UNKNOWN_INLINE_TAG;
784 }
786 @Override
787 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
788 return v.visitUnknownInlineTag(this, d);
789 }
791 @Override
792 public String getTagName() {
793 return name.toString();
794 }
796 @Override
797 public List<? extends DocTree> getContent() {
798 return content;
799 }
800 }
802 public static class DCValue extends DCInlineTag implements ValueTree {
803 public final DCReference ref;
805 DCValue(DCReference ref) {
806 this.ref = ref;
807 }
809 @Override
810 public Kind getKind() {
811 return Kind.VALUE;
812 }
814 @Override
815 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
816 return v.visitValue(this, d);
817 }
819 @Override
820 public ReferenceTree getReference() {
821 return ref;
822 }
823 }
825 public static class DCVersion extends DCBlockTag implements VersionTree {
826 public final List<DCTree> body;
828 DCVersion(List<DCTree> body) {
829 this.body = body;
830 }
832 @Override
833 public Kind getKind() {
834 return Kind.VERSION;
835 }
837 @Override
838 public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
839 return v.visitVersion(this, d);
840 }
842 @Override
843 public List<? extends DocTree> getBody() {
844 return body;
845 }
846 }
848 }