8253736: Cleanup some of WorkArounds and usage thereof
Reviewed-by: vromero, ksrini
This commit is contained in:
parent
87d77eb2a0
commit
777804759f
src
jdk.compiler/share/classes/com/sun/tools/doclint
jdk.javadoc/share/classes/jdk/javadoc/internal
doclets
formats/html
toolkit
doclint
test/langtools/jdk/javadoc/doclet/constantValues
@ -30,6 +30,14 @@ import java.util.ServiceLoader;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.Plugin;
|
||||
|
||||
/**
|
||||
* The base class for the DocLint service used by javac.
|
||||
*
|
||||
* <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>
|
||||
*/
|
||||
public abstract class DocLint implements Plugin {
|
||||
public static final String XMSGS_OPTION = "-Xmsgs";
|
||||
public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:";
|
||||
|
@ -25,9 +25,13 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.formats.html;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
@ -36,7 +40,6 @@ import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
|
||||
import com.sun.source.util.DocTreePath;
|
||||
|
||||
import jdk.javadoc.doclet.Doclet;
|
||||
import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.doclet.Reporter;
|
||||
@ -201,7 +204,7 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
docPaths = new DocPaths(utils);
|
||||
setCreateOverview();
|
||||
setTopFile(docEnv);
|
||||
workArounds.initDocLint(options.doclintOpts(), tagletManager.getAllTagletNames());
|
||||
initDocLint(options.doclintOpts(), tagletManager.getAllTagletNames());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -321,12 +324,12 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean showMessage(DocTreePath path, String key) {
|
||||
return (path == null || workArounds.haveDocLint());
|
||||
return (path == null || !haveDocLint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showMessage(Element e, String key) {
|
||||
return (e == null || workArounds.haveDocLint());
|
||||
return (e == null || !haveDocLint());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,18 +25,36 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.DocTreePath;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.util.DefinedBy;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
import jdk.javadoc.doclet.Doclet;
|
||||
@ -44,7 +62,6 @@ import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.doclet.Reporter;
|
||||
import jdk.javadoc.doclet.StandardDoclet;
|
||||
import jdk.javadoc.doclet.Taglet;
|
||||
import jdk.javadoc.internal.doclets.formats.html.HtmlDoclet;
|
||||
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
|
||||
import jdk.javadoc.internal.doclets.toolkit.taglets.TagletManager;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Comparators;
|
||||
@ -60,6 +77,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils.Pair;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberCache;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable;
|
||||
import jdk.javadoc.internal.doclint.DocLint;
|
||||
|
||||
/**
|
||||
* Configure the output based on the options. Doclets should sub-class
|
||||
@ -201,7 +219,7 @@ public abstract class BaseConfiguration {
|
||||
* @apiNote The {@code doclet} parameter is used when
|
||||
* {@link Taglet#init(DocletEnvironment, Doclet) initializing tags}.
|
||||
* Some doclets (such as the {@link StandardDoclet}), may delegate to another
|
||||
* (such as the {@link HtmlDoclet}). In such cases, the primary doclet (i.e
|
||||
* (such as the {@code HtmlDoclet}). In such cases, the primary doclet (i.e
|
||||
* {@code StandardDoclet}) should be provided here, and not any internal
|
||||
* class like {@code HtmlDoclet}.
|
||||
*
|
||||
@ -367,7 +385,16 @@ public abstract class BaseConfiguration {
|
||||
group.checkPackageGroups(grp.first, grp.second);
|
||||
}
|
||||
});
|
||||
overviewElement = new OverviewElement(workArounds.getUnnamedPackage(), getOverviewPath());
|
||||
|
||||
PackageElement unnamedPackage;
|
||||
Elements elementUtils = utils.elementUtils;
|
||||
if (docEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_9) >= 0) {
|
||||
ModuleElement unnamedModule = elementUtils.getModuleElement("");
|
||||
unnamedPackage = elementUtils.getPackageElement(unnamedModule, "");
|
||||
} else {
|
||||
unnamedPackage = elementUtils.getPackageElement("");
|
||||
}
|
||||
overviewElement = new OverviewElement(unnamedPackage, getOverviewPath());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -690,4 +717,91 @@ public abstract class BaseConfiguration {
|
||||
|| javafxModule.isUnnamed()
|
||||
|| javafxModule.getQualifiedName().contentEquals("javafx.base");
|
||||
}
|
||||
|
||||
|
||||
//<editor-fold desc="DocLint support">
|
||||
|
||||
private DocLint doclint;
|
||||
|
||||
Map<CompilationUnitTree, Boolean> shouldCheck = new HashMap<>();
|
||||
|
||||
public void runDocLint(TreePath path) {
|
||||
CompilationUnitTree unit = path.getCompilationUnit();
|
||||
if (doclint != null && shouldCheck.computeIfAbsent(unit, doclint::shouldCheck)) {
|
||||
doclint.scan(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes DocLint, if appropriate, depending on options derived
|
||||
* from the doclet command-line options, and the set of custom tags
|
||||
* that should be ignored by DocLint.
|
||||
*
|
||||
* DocLint is not enabled if the option {@code -Xmsgs:none} is given,
|
||||
* and it is not followed by any options to enable any groups.
|
||||
* Note that arguments for {@code -Xmsgs:} can be given individually
|
||||
* in separate {@code -Xmsgs:} options, or in a comma-separated list
|
||||
* for a single option. For example, the following are equivalent:
|
||||
* <ul>
|
||||
* <li>{@code -Xmsgs:all} {@code -Xmsgs:-html}
|
||||
* <li>{@code -Xmsgs:all,-html}
|
||||
* </ul>
|
||||
*
|
||||
* @param opts options for DocLint, derived from the corresponding doclet
|
||||
* command-line options
|
||||
* @param customTagNames the names of custom tags, to be ignored by doclint
|
||||
*/
|
||||
public void initDocLint(List<String> opts, Set<String> customTagNames) {
|
||||
List<String> doclintOpts = new ArrayList<>();
|
||||
|
||||
// basic analysis of -Xmsgs and -Xmsgs: options to see if doclint is enabled
|
||||
Set<String> groups = new HashSet<>();
|
||||
boolean seenXmsgs = false;
|
||||
for (String opt : opts) {
|
||||
if (opt.equals(DocLint.XMSGS_OPTION)) {
|
||||
groups.add("all");
|
||||
seenXmsgs = true;
|
||||
} else if (opt.startsWith(DocLint.XMSGS_CUSTOM_PREFIX)) {
|
||||
String[] args = opt.substring(DocLint.XMSGS_CUSTOM_PREFIX.length())
|
||||
.split(DocLint.SEPARATOR);
|
||||
for (String a : args) {
|
||||
if (a.equals("none")) {
|
||||
groups.clear();
|
||||
} else if (a.startsWith("-")) {
|
||||
groups.remove(a.substring(1));
|
||||
} else {
|
||||
groups.add(a);
|
||||
}
|
||||
}
|
||||
seenXmsgs = true;
|
||||
}
|
||||
doclintOpts.add(opt);
|
||||
}
|
||||
|
||||
if (seenXmsgs) {
|
||||
if (groups.isEmpty()) {
|
||||
// no groups enabled; do not init doclint
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// no -Xmsgs options of any kind, use default
|
||||
doclintOpts.add(DocLint.XMSGS_OPTION);
|
||||
}
|
||||
|
||||
if (!customTagNames.isEmpty()) {
|
||||
String customTags = String.join(DocLint.SEPARATOR, customTagNames);
|
||||
doclintOpts.add(DocLint.XCUSTOM_TAGS_PREFIX + customTags);
|
||||
}
|
||||
|
||||
doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + "html5");
|
||||
|
||||
doclint = new DocLint();
|
||||
doclint.init(docEnv.getDocTrees(), docEnv.getElementUtils(), docEnv.getTypeUtils(),
|
||||
doclintOpts.toArray(new String[0]));
|
||||
}
|
||||
|
||||
public boolean haveDocLint() {
|
||||
return (doclint != null);
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
|
@ -427,8 +427,8 @@ public class CommentUtils {
|
||||
}
|
||||
break;
|
||||
case PACKAGE:
|
||||
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
|
||||
pe = (PackageElement)e;
|
||||
pe = (PackageElement) e;
|
||||
fo = configuration.workArounds.getJavaFileObject(pe);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
|
@ -116,8 +116,9 @@ public class Messages {
|
||||
* @param args optional arguments to be replaced in the message.
|
||||
*/
|
||||
public void warning(DocTreePath path, String key, Object... args) {
|
||||
if (configuration.showMessage(path, key))
|
||||
if (configuration.showMessage(path, key)) {
|
||||
report(WARNING, path, resources.getText(key, args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,7 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
|
||||
@ -94,110 +95,36 @@ public class WorkArounds {
|
||||
public final BaseConfiguration configuration;
|
||||
public final ToolEnvironment toolEnv;
|
||||
public final Utils utils;
|
||||
|
||||
private DocLint doclint;
|
||||
public final Elements elementUtils;
|
||||
public final Types typeUtils;
|
||||
public final com.sun.tools.javac.code.Types javacTypes;
|
||||
|
||||
public WorkArounds(BaseConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.utils = this.configuration.utils;
|
||||
this.toolEnv = ((DocEnvImpl)this.configuration.docEnv).toolEnv;
|
||||
}
|
||||
|
||||
Map<CompilationUnitTree, Boolean> shouldCheck = new HashMap<>();
|
||||
// TODO: fix this up correctly
|
||||
public void runDocLint(TreePath path) {
|
||||
CompilationUnitTree unit = path.getCompilationUnit();
|
||||
if (doclint != null && shouldCheck.computeIfAbsent(unit, doclint::shouldCheck)) {
|
||||
doclint.scan(path);
|
||||
}
|
||||
}
|
||||
elementUtils = configuration.docEnv.getElementUtils();
|
||||
typeUtils = configuration.docEnv.getTypeUtils();
|
||||
|
||||
/**
|
||||
* Initializes doclint, if appropriate, depending on options derived
|
||||
* from the doclet command-line options, and the set of custom tags
|
||||
* that should be ignored by doclint.
|
||||
*
|
||||
* DocLint is not enabled if the option {@code -Xmsgs:none} is given,
|
||||
* and it is not followed by any options to enable any groups.
|
||||
* Note that arguments for {@code -Xmsgs:} can be given individually
|
||||
* in separate {@code -Xmsgs:} options, or in a comma-separated list
|
||||
* for a single option. For example, the following are equivalent:
|
||||
* <ul>
|
||||
* <li>{@code -Xmsgs:all} {@code -Xmsgs:-html}
|
||||
* <li>{@code -Xmsgs:all,-html}
|
||||
* </ul>
|
||||
*
|
||||
* @param opts options for doclint, derived from the corresponding doclet
|
||||
* command-line options
|
||||
* @param customTagNames the names of custom tags, to be ignored by doclint
|
||||
*/
|
||||
public void initDocLint(List<String> opts, Set<String> customTagNames) {
|
||||
List<String> doclintOpts = new ArrayList<>();
|
||||
|
||||
// basic analysis of -Xmsgs and -Xmsgs: options to see if doclint is enabled
|
||||
Set<String> groups = new HashSet<>();
|
||||
boolean seenXmsgs = false;
|
||||
for (String opt : opts) {
|
||||
if (opt.equals(DocLint.XMSGS_OPTION)) {
|
||||
groups.add("all");
|
||||
seenXmsgs = true;
|
||||
} else if (opt.startsWith(DocLint.XMSGS_CUSTOM_PREFIX)) {
|
||||
String[] args = opt.substring(DocLint.XMSGS_CUSTOM_PREFIX.length())
|
||||
.split(DocLint.SEPARATOR);
|
||||
for (String a : args) {
|
||||
if (a.equals("none")) {
|
||||
groups.clear();
|
||||
} else if (a.startsWith("-")) {
|
||||
groups.remove(a.substring(1));
|
||||
} else {
|
||||
groups.add(a);
|
||||
}
|
||||
}
|
||||
seenXmsgs = true;
|
||||
}
|
||||
doclintOpts.add(opt);
|
||||
}
|
||||
|
||||
if (seenXmsgs) {
|
||||
if (groups.isEmpty()) {
|
||||
// no groups enabled; do not init doclint
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// no -Xmsgs options of any kind, use default
|
||||
doclintOpts.add(DocLint.XMSGS_OPTION);
|
||||
}
|
||||
|
||||
if (!customTagNames.isEmpty()) {
|
||||
String customTags = String.join(DocLint.SEPARATOR, customTagNames);
|
||||
doclintOpts.add(DocLint.XCUSTOM_TAGS_PREFIX + customTags);
|
||||
}
|
||||
|
||||
doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + "html5");
|
||||
|
||||
JavacTask t = BasicJavacTask.instance(toolEnv.context);
|
||||
doclint = new DocLint();
|
||||
doclint.init(t, doclintOpts.toArray(new String[0]), false);
|
||||
}
|
||||
|
||||
// TODO: fix this up correctly
|
||||
public boolean haveDocLint() {
|
||||
return (doclint == null);
|
||||
// Note: this one use of DocEnvImpl is what prevents us tunnelling extra
|
||||
// info from a doclet to its taglets via a doclet-specific subtype of
|
||||
// DocletEnvironment.
|
||||
toolEnv = ((DocEnvImpl)this.configuration.docEnv).toolEnv;
|
||||
javacTypes = toolEnv.getTypes();
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This method exists because of a bug in javac which does not
|
||||
* handle "@deprecated tag in package-info.java", when this issue
|
||||
* is fixed this method and its uses must be jettisoned.
|
||||
* handle "@deprecated tag in package-info.java", when this issue
|
||||
* is fixed this method and its uses must be jettisoned.
|
||||
*/
|
||||
public boolean isDeprecated0(Element e) {
|
||||
if (!utils.getDeprecatedTrees(e).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
JavacTypes jctypes = ((DocEnvImpl)configuration.docEnv).toolEnv.typeutils;
|
||||
TypeMirror deprecatedType = utils.getDeprecatedType();
|
||||
for (AnnotationMirror anno : e.getAnnotationMirrors()) {
|
||||
if (jctypes.isSameType(anno.getAnnotationType().asElement().asType(), deprecatedType))
|
||||
if (typeUtils.isSameType(anno.getAnnotationType().asElement().asType(), deprecatedType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -208,24 +135,11 @@ public class WorkArounds {
|
||||
return ((Attribute)aDesc).isSynthesized();
|
||||
}
|
||||
|
||||
// TODO: fix the caller
|
||||
public Object getConstValue(VariableElement ve) {
|
||||
return ((VarSymbol)ve).getConstValue();
|
||||
}
|
||||
|
||||
// TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
|
||||
public Map<Element, TreePath> getElementToTreePath() {
|
||||
return toolEnv.elementToTreePath;
|
||||
}
|
||||
|
||||
// TODO: we need ElementUtils.getPackage to cope with input strings
|
||||
// to return the proper unnamedPackage for all supported releases.
|
||||
PackageElement getUnnamedPackage() {
|
||||
return (Feature.MODULES.allowedInSource(toolEnv.source))
|
||||
? toolEnv.syms.unnamedModule.unnamedPackage
|
||||
: toolEnv.syms.noModule.unnamedPackage;
|
||||
}
|
||||
|
||||
// TODO: implement in either jx.l.m API (preferred) or DocletEnvironment.
|
||||
FileObject getJavaFileObject(PackageElement packageElement) {
|
||||
return ((PackageSymbol)packageElement).sourcefile;
|
||||
@ -238,7 +152,7 @@ public class WorkArounds {
|
||||
// search by qualified name in current module first
|
||||
ModuleElement me = utils.containingModule(klass);
|
||||
if (me != null) {
|
||||
te = configuration.docEnv.getElementUtils().getTypeElement(me, className);
|
||||
te = elementUtils.getTypeElement(me, className);
|
||||
if (te != null) {
|
||||
return te;
|
||||
}
|
||||
@ -290,17 +204,12 @@ public class WorkArounds {
|
||||
}
|
||||
|
||||
// finally, search by qualified name in all modules
|
||||
te = configuration.docEnv.getElementUtils().getTypeElement(className);
|
||||
if (te != null) {
|
||||
return te;
|
||||
}
|
||||
|
||||
return null; // not found
|
||||
return elementUtils.getTypeElement(className);
|
||||
}
|
||||
|
||||
// TODO: need to re-implement this using j.l.m. correctly!, this has
|
||||
// implications on testInterface, the note here is that javac's supertype
|
||||
// does the right thing returning Parameters in scope.
|
||||
// implications on testInterface, the note here is that javac's supertype
|
||||
// does the right thing returning Parameters in scope.
|
||||
/**
|
||||
* Return the type containing the method that this method overrides.
|
||||
* It may be a <code>TypeElement</code> or a <code>TypeParameterElement</code>.
|
||||
@ -311,14 +220,14 @@ public class WorkArounds {
|
||||
if (utils.isStatic(method)) {
|
||||
return null;
|
||||
}
|
||||
MethodSymbol sym = (MethodSymbol)method;
|
||||
MethodSymbol sym = (MethodSymbol) method;
|
||||
ClassSymbol origin = (ClassSymbol) sym.owner;
|
||||
for (com.sun.tools.javac.code.Type t = toolEnv.getTypes().supertype(origin.type);
|
||||
for (com.sun.tools.javac.code.Type t = javacTypes.supertype(origin.type);
|
||||
t.hasTag(TypeTag.CLASS);
|
||||
t = toolEnv.getTypes().supertype(t)) {
|
||||
t = javacTypes.supertype(t)) {
|
||||
ClassSymbol c = (ClassSymbol) t.tsym;
|
||||
for (com.sun.tools.javac.code.Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
|
||||
if (sym.overrides(sym2, origin, toolEnv.getTypes(), true)) {
|
||||
if (sym.overrides(sym2, origin, javacTypes, true)) {
|
||||
// Ignore those methods that may be a simple override
|
||||
// and allow the real API method to be found.
|
||||
if (sym2.type.hasTag(TypeTag.METHOD) &&
|
||||
@ -353,10 +262,10 @@ public class WorkArounds {
|
||||
!rider.isStatic() &&
|
||||
|
||||
// Symbol.overrides assumes the following
|
||||
ridee.isMemberOf(origin, toolEnv.getTypes()) &&
|
||||
ridee.isMemberOf(origin, javacTypes) &&
|
||||
|
||||
// check access, signatures and check return types
|
||||
rider.overrides(ridee, origin, toolEnv.getTypes(), true);
|
||||
rider.overrides(ridee, origin, javacTypes, true);
|
||||
}
|
||||
|
||||
// TODO: jx.l.m ?
|
||||
|
@ -107,9 +107,9 @@ import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.model.JavacTypes;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
|
||||
import jdk.javadoc.internal.doclets.toolkit.CommentUtils;
|
||||
import jdk.javadoc.internal.doclets.toolkit.CommentUtils.DocCommentInfo;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
import jdk.javadoc.internal.doclets.toolkit.WorkArounds;
|
||||
import jdk.javadoc.internal.doclets.toolkit.taglets.BaseTaglet;
|
||||
import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet;
|
||||
import jdk.javadoc.internal.tool.DocEnvImpl;
|
||||
@ -2271,60 +2271,56 @@ public class Utils {
|
||||
public String constantValueExpression(VariableElement ve) {
|
||||
if (cve == null)
|
||||
cve = new ConstantValueExpression();
|
||||
return cve.constantValueExpression(configuration.workArounds, ve);
|
||||
return cve.visit(ve.asType(), ve.getConstantValue());
|
||||
}
|
||||
|
||||
private static class ConstantValueExpression {
|
||||
public String constantValueExpression(WorkArounds workArounds, VariableElement ve) {
|
||||
return new TypeKindVisitor9<String, Object>() {
|
||||
/* TODO: we need to fix this correctly.
|
||||
* we have a discrepancy here, note the use of getConstValue
|
||||
* vs. getConstantValue, at some point we need to use
|
||||
* getConstantValue.
|
||||
* In the legacy world byte and char primitives appear as Integer values,
|
||||
* thus a byte value of 127 will appear as 127, but in the new world,
|
||||
* a byte value appears as Byte thus 0x7f will be printed, similarly
|
||||
* chars will be translated to \n, \r etc. however, in the new world,
|
||||
* they will be printed as decimal values. The new world is correct,
|
||||
* and we should fix this by using getConstantValue and the visitor to
|
||||
* address this in the future.
|
||||
*/
|
||||
@Override
|
||||
public String visitPrimitiveAsBoolean(PrimitiveType t, Object val) {
|
||||
return (int)val == 0 ? "false" : "true";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsDouble(PrimitiveType t, Object val) {
|
||||
return sourceForm(((Double)val), 'd');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsFloat(PrimitiveType t, Object val) {
|
||||
return sourceForm(((Float)val).doubleValue(), 'f');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsLong(PrimitiveType t, Object val) {
|
||||
return val + "L";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String defaultAction(TypeMirror e, Object val) {
|
||||
if (val == null)
|
||||
return null;
|
||||
else if (val instanceof Character)
|
||||
return sourceForm(((Character)val));
|
||||
else if (val instanceof Byte)
|
||||
return sourceForm(((Byte)val));
|
||||
else if (val instanceof String)
|
||||
return sourceForm((String)val);
|
||||
return val.toString(); // covers int, short
|
||||
}
|
||||
}.visit(ve.asType(), workArounds.getConstValue(ve));
|
||||
// We could also use Elements.getConstantValueExpression, which provides
|
||||
// similar functionality, but which also includes casts to provide valid
|
||||
// compilable constants: e.g. (byte) 0x7f
|
||||
private static class ConstantValueExpression extends TypeKindVisitor9<String, Object> {
|
||||
@Override
|
||||
public String visitPrimitiveAsBoolean(PrimitiveType t, Object val) {
|
||||
return ((boolean) val) ? "true" : "false";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsByte(PrimitiveType t, Object val) {
|
||||
return "0x" + Integer.toString(((Byte) val) & 0xff, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsChar(PrimitiveType t, Object val) {
|
||||
StringBuilder buf = new StringBuilder(8);
|
||||
buf.append('\'');
|
||||
sourceChar((char) val, buf);
|
||||
buf.append('\'');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsDouble(PrimitiveType t, Object val) {
|
||||
return sourceForm(((Double) val), 'd');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsFloat(PrimitiveType t, Object val) {
|
||||
return sourceForm(((Float) val).doubleValue(), 'f');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitPrimitiveAsLong(PrimitiveType t, Object val) {
|
||||
return val + "L";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String defaultAction(TypeMirror e, Object val) {
|
||||
if (val == null)
|
||||
return null;
|
||||
else if (val instanceof String)
|
||||
return sourceForm((String) val);
|
||||
return val.toString(); // covers int, short
|
||||
}
|
||||
|
||||
// where
|
||||
private String sourceForm(double v, char suffix) {
|
||||
if (Double.isNaN(v))
|
||||
return "0" + suffix + "/0" + suffix;
|
||||
@ -2335,22 +2331,10 @@ public class Utils {
|
||||
return v + (suffix == 'f' || suffix == 'F' ? "" + suffix : "");
|
||||
}
|
||||
|
||||
private String sourceForm(char c) {
|
||||
StringBuilder buf = new StringBuilder(8);
|
||||
buf.append('\'');
|
||||
sourceChar(c, buf);
|
||||
buf.append('\'');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String sourceForm(byte c) {
|
||||
return "0x" + Integer.toString(c & 0xff, 16);
|
||||
}
|
||||
|
||||
private String sourceForm(String s) {
|
||||
StringBuilder buf = new StringBuilder(s.length() + 5);
|
||||
buf.append('\"');
|
||||
for (int i=0; i<s.length(); i++) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
sourceChar(c, buf);
|
||||
}
|
||||
@ -2360,31 +2344,33 @@ public class Utils {
|
||||
|
||||
private void sourceChar(char c, StringBuilder buf) {
|
||||
switch (c) {
|
||||
case '\b': buf.append("\\b"); return;
|
||||
case '\t': buf.append("\\t"); return;
|
||||
case '\n': buf.append("\\n"); return;
|
||||
case '\f': buf.append("\\f"); return;
|
||||
case '\r': buf.append("\\r"); return;
|
||||
case '\"': buf.append("\\\""); return;
|
||||
case '\'': buf.append("\\\'"); return;
|
||||
case '\\': buf.append("\\\\"); return;
|
||||
default:
|
||||
if (isPrintableAscii(c)) {
|
||||
buf.append(c); return;
|
||||
case '\b' -> buf.append("\\b");
|
||||
case '\t' -> buf.append("\\t");
|
||||
case '\n' -> buf.append("\\n");
|
||||
case '\f' -> buf.append("\\f");
|
||||
case '\r' -> buf.append("\\r");
|
||||
case '\"' -> buf.append("\\\"");
|
||||
case '\'' -> buf.append("\\\'");
|
||||
case '\\' -> buf.append("\\\\");
|
||||
default -> {
|
||||
if (isPrintableAscii(c)) {
|
||||
buf.append(c);
|
||||
return;
|
||||
}
|
||||
unicodeEscape(c, buf);
|
||||
}
|
||||
unicodeEscape(c, buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void unicodeEscape(char c, StringBuilder buf) {
|
||||
final String chars = "0123456789abcdef";
|
||||
buf.append("\\u");
|
||||
buf.append(chars.charAt(15 & (c>>12)));
|
||||
buf.append(chars.charAt(15 & (c>>8)));
|
||||
buf.append(chars.charAt(15 & (c>>4)));
|
||||
buf.append(chars.charAt(15 & (c>>0)));
|
||||
buf.append(chars.charAt(15 & (c >> 12)));
|
||||
buf.append(chars.charAt(15 & (c >> 8)));
|
||||
buf.append(chars.charAt(15 & (c >> 4)));
|
||||
buf.append(chars.charAt(15 & (c >> 0)));
|
||||
}
|
||||
|
||||
private boolean isPrintableAscii(char c) {
|
||||
return c >= ' ' && c <= '~';
|
||||
}
|
||||
@ -2722,7 +2708,7 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
// run doclint even if docCommentTree is null, to trigger checks for missing comments
|
||||
configuration.workArounds.runDocLint(path);
|
||||
configuration.runDocLint(path);
|
||||
}
|
||||
dcTreeCache.put(element, info);
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
@ -46,8 +48,8 @@ import com.sun.source.tree.PackageTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.tree.VariableTree;
|
||||
import com.sun.source.util.DocTrees;
|
||||
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;
|
||||
@ -283,27 +285,8 @@ public class DocLint extends com.sun.tools.doclint.DocLint {
|
||||
|
||||
public void init(JavacTask task, String[] args, boolean addTaskListener) {
|
||||
env = new Env();
|
||||
for (String arg : args) {
|
||||
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.startsWith(XCUSTOM_TAGS_PREFIX)) {
|
||||
env.setCustomTags(arg.substring(arg.indexOf(":") + 1));
|
||||
} else if (arg.startsWith(XHTML_VERSION_PREFIX)) {
|
||||
String argsVersion = arg.substring(arg.indexOf(":") + 1);
|
||||
HtmlVersion htmlVersion = HtmlVersion.getHtmlVersion(argsVersion);
|
||||
if (htmlVersion != null) {
|
||||
env.setHtmlVersion(htmlVersion);
|
||||
} else {
|
||||
throw new IllegalArgumentException(argsVersion);
|
||||
}
|
||||
} else if (arg.startsWith(XCHECK_PACKAGE)) {
|
||||
env.setCheckPackages(arg.substring(arg.indexOf(":") + 1));
|
||||
} else
|
||||
throw new IllegalArgumentException(arg);
|
||||
}
|
||||
env.init(task);
|
||||
processArgs(env, args);
|
||||
|
||||
checker = new Checker(env);
|
||||
|
||||
@ -346,6 +329,37 @@ public class DocLint extends com.sun.tools.doclint.DocLint {
|
||||
}
|
||||
}
|
||||
|
||||
public void init(DocTrees trees, Elements elements, Types types, String... args) {
|
||||
env = new Env();
|
||||
env.init(trees, elements, types);
|
||||
processArgs(env, args);
|
||||
|
||||
checker = new Checker(env);
|
||||
}
|
||||
|
||||
private void processArgs(Env env, String... args) {
|
||||
for (String arg : args) {
|
||||
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.startsWith(XCUSTOM_TAGS_PREFIX)) {
|
||||
env.setCustomTags(arg.substring(arg.indexOf(":") + 1));
|
||||
} else if (arg.startsWith(XHTML_VERSION_PREFIX)) {
|
||||
String argsVersion = arg.substring(arg.indexOf(":") + 1);
|
||||
HtmlVersion htmlVersion = HtmlVersion.getHtmlVersion(argsVersion);
|
||||
if (htmlVersion != null) {
|
||||
env.setHtmlVersion(htmlVersion);
|
||||
} else {
|
||||
throw new IllegalArgumentException(argsVersion);
|
||||
}
|
||||
} else if (arg.startsWith(XCHECK_PACKAGE)) {
|
||||
env.setCheckPackages(arg.substring(arg.indexOf(":") + 1));
|
||||
} else
|
||||
throw new IllegalArgumentException(arg);
|
||||
}
|
||||
}
|
||||
|
||||
public void scan(TreePath p) {
|
||||
DocCommentTree dc = env.trees.getDocCommentTree(p);
|
||||
checker.scan(dc, p);
|
||||
|
@ -57,15 +57,15 @@ public class TestConstantValuesDriver extends JavadocTester {
|
||||
"""
|
||||
<code id="TestConstantValues.BYTE_MAX_VALUE">public static final byte</code></td>
|
||||
<th class="col-second" scope="row"><code><a href="TestConstantValues.html#BYTE_MAX_VALUE">BYTE_MAX_VALUE</a></code></th>
|
||||
<td class="col-last"><code>127</code></td>""",
|
||||
<td class="col-last"><code>0x7f</code></td>""",
|
||||
"""
|
||||
<code id="TestConstantValues.BYTE_MIN_VALUE">public static final byte</code></td>
|
||||
<th class="col-second" scope="row"><code><a href="TestConstantValues.html#BYTE_MIN_VALUE">BYTE_MIN_VALUE</a></code></th>
|
||||
<td class="col-last"><code>-127</code></td>""",
|
||||
<td class="col-last"><code>0x81</code></td>""",
|
||||
"""
|
||||
<code id="TestConstantValues.CHAR_MAX_VALUE">public static final char</code></td>
|
||||
<th class="col-second" scope="row"><code><a href="TestConstantValues.html#CHAR_MAX_VALUE">CHAR_MAX_VALUE</a></code></th>
|
||||
<td class="col-last"><code>65535</code></td>""",
|
||||
<td class="col-last"><code>'\\uffff'</code></td>""",
|
||||
"""
|
||||
<code id="TestConstantValues.DOUBLE_MAX_VALUE">public static final double</code></td>""",
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user