70 import javax.lang.model.util.Types;
71 import javax.tools.FileObject;
72 import javax.tools.JavaFileManager;
73 import javax.tools.JavaFileManager.Location;
74 import javax.tools.StandardLocation;
75
76 import com.sun.source.doctree.DocCommentTree;
77 import com.sun.source.doctree.DocTree;
78 import com.sun.source.doctree.DocTree.Kind;
79 import com.sun.source.doctree.ParamTree;
80 import com.sun.source.doctree.SerialFieldTree;
81 import com.sun.source.doctree.UnknownBlockTagTree;
82 import com.sun.source.tree.CompilationUnitTree;
83 import com.sun.source.tree.LineMap;
84 import com.sun.source.util.DocSourcePositions;
85 import com.sun.source.util.DocTrees;
86 import com.sun.source.util.TreePath;
87 import com.sun.tools.javac.model.JavacTypes;
88 import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
89 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
90 import jdk.javadoc.internal.doclets.toolkit.CommentUtils.DocCommentDuo;
91 import jdk.javadoc.internal.doclets.toolkit.Messages;
92 import jdk.javadoc.internal.doclets.toolkit.Resources;
93 import jdk.javadoc.internal.doclets.toolkit.WorkArounds;
94 import jdk.javadoc.internal.doclets.toolkit.taglets.BaseTaglet;
95 import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet;
96 import jdk.javadoc.internal.tool.DocEnvImpl;
97
98 import static javax.lang.model.element.ElementKind.*;
99 import static javax.lang.model.element.Modifier.*;
100 import static javax.lang.model.type.TypeKind.*;
101
102 import static com.sun.source.doctree.DocTree.Kind.*;
103 import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuilder.MAX_CONSTANT_VALUE_INDEX_LENGTH;
104
105 /**
106 * Utilities Class for Doclets.
107 *
108 * <p><b>This is NOT part of any supported API.
109 * If you write code that depends on this, you do so at your own risk.
110 * This code and its internal interfaces are subject to change or
111 * deletion without notice.</b>
112 */
113 public class Utils {
114 public final BaseConfiguration configuration;
115 public final Messages messages;
116 public final Resources resources;
117 public final DocTrees docTrees;
118 public final Elements elementUtils;
119 public final Types typeUtils;
120 public final JavaScriptScanner javaScriptScanner;
121
122 public Utils(BaseConfiguration c) {
123 configuration = c;
124 messages = configuration.getMessages();
125 resources = configuration.getResources();
126 elementUtils = c.docEnv.getElementUtils();
127 typeUtils = c.docEnv.getTypeUtils();
128 docTrees = c.docEnv.getDocTrees();
129 javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
130 }
131
132 // our own little symbol table
133 private HashMap<String, TypeMirror> symtab = new HashMap<>();
134
135 public TypeMirror getSymbol(String signature) {
136 TypeMirror type = symtab.get(signature);
137 if (type == null) {
138 TypeElement typeElement = elementUtils.getTypeElement(signature);
139 if (typeElement == null)
140 return null;
141 type = typeElement.asType();
142 if (type == null)
143 return null;
373 return e.getModifiers().contains(Modifier.DEFAULT);
374 }
375
376 public boolean isPackagePrivate(Element e) {
377 return !(isPublic(e) || isPrivate(e) || isProtected(e));
378 }
379
380 public boolean isPrivate(Element e) {
381 return e.getModifiers().contains(Modifier.PRIVATE);
382 }
383
384 public boolean isProtected(Element e) {
385 return e.getModifiers().contains(Modifier.PROTECTED);
386 }
387
388 public boolean isPublic(Element e) {
389 return e.getModifiers().contains(Modifier.PUBLIC);
390 }
391
392 public boolean isProperty(String name) {
393 return configuration.javafx && name.endsWith("Property");
394 }
395
396 public String getPropertyName(String name) {
397 return isProperty(name)
398 ? name.substring(0, name.length() - "Property".length())
399 : name;
400 }
401
402 public String getPropertyLabel(String name) {
403 return name.substring(0, name.lastIndexOf("Property"));
404 }
405
406 public boolean isOverviewElement(Element e) {
407 return e.getKind() == ElementKind.OTHER;
408 }
409
410 public boolean isStatic(Element e) {
411 return e.getModifiers().contains(Modifier.STATIC);
412 }
413
1331 return t.toString();
1332 }
1333
1334 @Override
1335 protected String defaultAction(TypeMirror e, Void p) {
1336 return e.toString();
1337 }
1338 }.visit(t);
1339 }
1340
1341 /**
1342 * Replace all tabs in a string with the appropriate number of spaces.
1343 * The string may be a multi-line string.
1344 * @param text the text for which the tabs should be expanded
1345 * @return the text with all tabs expanded
1346 */
1347 public String replaceTabs(String text) {
1348 if (!text.contains("\t"))
1349 return text;
1350
1351 final int tabLength = configuration.sourcetab;
1352 final String whitespace = configuration.tabSpaces;
1353 final int textLength = text.length();
1354 StringBuilder result = new StringBuilder(textLength);
1355 int pos = 0;
1356 int lineLength = 0;
1357 for (int i = 0; i < textLength; i++) {
1358 char ch = text.charAt(i);
1359 switch (ch) {
1360 case '\n': case '\r':
1361 lineLength = 0;
1362 break;
1363 case '\t':
1364 result.append(text, pos, i);
1365 int spaceCount = tabLength - lineLength % tabLength;
1366 result.append(whitespace, 0, spaceCount);
1367 lineLength += spaceCount;
1368 pos = i + 1;
1369 break;
1370 default:
1371 lineLength++;
1372 }
1464 }
1465 if ((propertyName == null) || propertyName.isEmpty()){
1466 return "";
1467 }
1468 return propertyName.substring(0, 1).toLowerCase(configuration.getLocale())
1469 + propertyName.substring(1);
1470 }
1471
1472 /**
1473 * Returns true if the element is included, contains @hidden tag,
1474 * or if javafx flag is present and element contains @treatAsPrivate
1475 * tag.
1476 * @param e the queried element
1477 * @return true if it exists, false otherwise
1478 */
1479 public boolean hasHiddenTag(Element e) {
1480 // prevent needless tests on elements which are not included
1481 if (!isIncluded(e)) {
1482 return false;
1483 }
1484 if (configuration.javafx &&
1485 hasBlockTag(e, DocTree.Kind.UNKNOWN_BLOCK_TAG, "treatAsPrivate")) {
1486 return true;
1487 }
1488 return hasBlockTag(e, DocTree.Kind.HIDDEN);
1489 }
1490
1491 /**
1492 * Returns true if the method has no comments, or a lone @inheritDoc.
1493 * @param m a method
1494 * @return true if there are no comments, false otherwise
1495 */
1496 public boolean isSimpleOverride(ExecutableElement m) {
1497 if (!configuration.summarizeOverriddenMethods ||
1498 !isIncluded(m)) {
1499 return false;
1500 }
1501
1502 if (!getBlockTags(m).isEmpty() || isDeprecated(m))
1503 return false;
1504
1505 List<? extends DocTree> fullBody = getFullBody(m);
1506 return fullBody.isEmpty() ||
1507 (fullBody.size() == 1 && fullBody.get(0).getKind().equals(Kind.INHERIT_DOC));
1508 }
1509
1510 /**
1511 * In case of JavaFX mode on, filters out classes that are private,
1512 * package private, these are not documented in JavaFX mode, also
1513 * remove those classes that have @hidden or @treatAsPrivate comment tag.
1514 *
1515 * @param classlist a collection of TypeElements
1516 * @param javafx set to true if in JavaFX mode.
1517 * @return list of filtered classes.
|
70 import javax.lang.model.util.Types;
71 import javax.tools.FileObject;
72 import javax.tools.JavaFileManager;
73 import javax.tools.JavaFileManager.Location;
74 import javax.tools.StandardLocation;
75
76 import com.sun.source.doctree.DocCommentTree;
77 import com.sun.source.doctree.DocTree;
78 import com.sun.source.doctree.DocTree.Kind;
79 import com.sun.source.doctree.ParamTree;
80 import com.sun.source.doctree.SerialFieldTree;
81 import com.sun.source.doctree.UnknownBlockTagTree;
82 import com.sun.source.tree.CompilationUnitTree;
83 import com.sun.source.tree.LineMap;
84 import com.sun.source.util.DocSourcePositions;
85 import com.sun.source.util.DocTrees;
86 import com.sun.source.util.TreePath;
87 import com.sun.tools.javac.model.JavacTypes;
88 import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
89 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
90 import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
91 import jdk.javadoc.internal.doclets.toolkit.CommentUtils.DocCommentDuo;
92 import jdk.javadoc.internal.doclets.toolkit.Messages;
93 import jdk.javadoc.internal.doclets.toolkit.Resources;
94 import jdk.javadoc.internal.doclets.toolkit.WorkArounds;
95 import jdk.javadoc.internal.doclets.toolkit.taglets.BaseTaglet;
96 import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet;
97 import jdk.javadoc.internal.tool.DocEnvImpl;
98
99 import static javax.lang.model.element.ElementKind.*;
100 import static javax.lang.model.element.Modifier.*;
101 import static javax.lang.model.type.TypeKind.*;
102
103 import static com.sun.source.doctree.DocTree.Kind.*;
104 import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuilder.MAX_CONSTANT_VALUE_INDEX_LENGTH;
105
106 /**
107 * Utilities Class for Doclets.
108 *
109 * <p><b>This is NOT part of any supported API.
110 * If you write code that depends on this, you do so at your own risk.
111 * This code and its internal interfaces are subject to change or
112 * deletion without notice.</b>
113 */
114 public class Utils {
115 public final BaseConfiguration configuration;
116 private final BaseOptions options;
117 private final Messages messages;
118 private final Resources resources;
119 public final DocTrees docTrees;
120 public final Elements elementUtils;
121 public final Types typeUtils;
122 private final JavaScriptScanner javaScriptScanner;
123
124 public Utils(BaseConfiguration c) {
125 configuration = c;
126 options = configuration.getOptions();
127 messages = configuration.getMessages();
128 resources = configuration.getResources();
129 elementUtils = c.docEnv.getElementUtils();
130 typeUtils = c.docEnv.getTypeUtils();
131 docTrees = c.docEnv.getDocTrees();
132 javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
133 }
134
135 // our own little symbol table
136 private HashMap<String, TypeMirror> symtab = new HashMap<>();
137
138 public TypeMirror getSymbol(String signature) {
139 TypeMirror type = symtab.get(signature);
140 if (type == null) {
141 TypeElement typeElement = elementUtils.getTypeElement(signature);
142 if (typeElement == null)
143 return null;
144 type = typeElement.asType();
145 if (type == null)
146 return null;
376 return e.getModifiers().contains(Modifier.DEFAULT);
377 }
378
379 public boolean isPackagePrivate(Element e) {
380 return !(isPublic(e) || isPrivate(e) || isProtected(e));
381 }
382
383 public boolean isPrivate(Element e) {
384 return e.getModifiers().contains(Modifier.PRIVATE);
385 }
386
387 public boolean isProtected(Element e) {
388 return e.getModifiers().contains(Modifier.PROTECTED);
389 }
390
391 public boolean isPublic(Element e) {
392 return e.getModifiers().contains(Modifier.PUBLIC);
393 }
394
395 public boolean isProperty(String name) {
396 return options.javafx && name.endsWith("Property");
397 }
398
399 public String getPropertyName(String name) {
400 return isProperty(name)
401 ? name.substring(0, name.length() - "Property".length())
402 : name;
403 }
404
405 public String getPropertyLabel(String name) {
406 return name.substring(0, name.lastIndexOf("Property"));
407 }
408
409 public boolean isOverviewElement(Element e) {
410 return e.getKind() == ElementKind.OTHER;
411 }
412
413 public boolean isStatic(Element e) {
414 return e.getModifiers().contains(Modifier.STATIC);
415 }
416
1334 return t.toString();
1335 }
1336
1337 @Override
1338 protected String defaultAction(TypeMirror e, Void p) {
1339 return e.toString();
1340 }
1341 }.visit(t);
1342 }
1343
1344 /**
1345 * Replace all tabs in a string with the appropriate number of spaces.
1346 * The string may be a multi-line string.
1347 * @param text the text for which the tabs should be expanded
1348 * @return the text with all tabs expanded
1349 */
1350 public String replaceTabs(String text) {
1351 if (!text.contains("\t"))
1352 return text;
1353
1354 final int tabLength = options.sourceTabSize;
1355 final String whitespace = " ".repeat(tabLength);
1356 final int textLength = text.length();
1357 StringBuilder result = new StringBuilder(textLength);
1358 int pos = 0;
1359 int lineLength = 0;
1360 for (int i = 0; i < textLength; i++) {
1361 char ch = text.charAt(i);
1362 switch (ch) {
1363 case '\n': case '\r':
1364 lineLength = 0;
1365 break;
1366 case '\t':
1367 result.append(text, pos, i);
1368 int spaceCount = tabLength - lineLength % tabLength;
1369 result.append(whitespace, 0, spaceCount);
1370 lineLength += spaceCount;
1371 pos = i + 1;
1372 break;
1373 default:
1374 lineLength++;
1375 }
1467 }
1468 if ((propertyName == null) || propertyName.isEmpty()){
1469 return "";
1470 }
1471 return propertyName.substring(0, 1).toLowerCase(configuration.getLocale())
1472 + propertyName.substring(1);
1473 }
1474
1475 /**
1476 * Returns true if the element is included, contains @hidden tag,
1477 * or if javafx flag is present and element contains @treatAsPrivate
1478 * tag.
1479 * @param e the queried element
1480 * @return true if it exists, false otherwise
1481 */
1482 public boolean hasHiddenTag(Element e) {
1483 // prevent needless tests on elements which are not included
1484 if (!isIncluded(e)) {
1485 return false;
1486 }
1487 if (options.javafx &&
1488 hasBlockTag(e, DocTree.Kind.UNKNOWN_BLOCK_TAG, "treatAsPrivate")) {
1489 return true;
1490 }
1491 return hasBlockTag(e, DocTree.Kind.HIDDEN);
1492 }
1493
1494 /**
1495 * Returns true if the method has no comments, or a lone @inheritDoc.
1496 * @param m a method
1497 * @return true if there are no comments, false otherwise
1498 */
1499 public boolean isSimpleOverride(ExecutableElement m) {
1500 if (!options.summarizeOverriddenMethods ||
1501 !isIncluded(m)) {
1502 return false;
1503 }
1504
1505 if (!getBlockTags(m).isEmpty() || isDeprecated(m))
1506 return false;
1507
1508 List<? extends DocTree> fullBody = getFullBody(m);
1509 return fullBody.isEmpty() ||
1510 (fullBody.size() == 1 && fullBody.get(0).getKind().equals(Kind.INHERIT_DOC));
1511 }
1512
1513 /**
1514 * In case of JavaFX mode on, filters out classes that are private,
1515 * package private, these are not documented in JavaFX mode, also
1516 * remove those classes that have @hidden or @treatAsPrivate comment tag.
1517 *
1518 * @param classlist a collection of TypeElements
1519 * @param javafx set to true if in JavaFX mode.
1520 * @return list of filtered classes.
|