8320234: Merge doclint.Env.AccessKind with tool.AccessKind

Reviewed-by: jjg
This commit is contained in:
Pavel Rappo 2023-11-20 17:36:33 +00:00
parent d6d7bdc774
commit 3aefd1ce71
7 changed files with 132 additions and 189 deletions

View File

@ -73,7 +73,7 @@ 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;
import jdk.javadoc.internal.doclint.Env;
import jdk.javadoc.internal.tool.AccessLevel;
/**
* Configure the output based on the options. Doclets should subclass
@ -654,10 +654,10 @@ public abstract class BaseConfiguration {
private boolean isDocLintGroupEnabled(jdk.javadoc.internal.doclint.Messages.Group group) {
// Use AccessKind.PUBLIC as a stand-in, since it is not common to
// set DocLint options per access kind (as is common with javac.)
// A more sophisticated solution might be to derive the access kind from the
// set DocLint options per access level (as is common with javac.)
// A more sophisticated solution might be to derive the access level from the
// element owning the comment, and its enclosing elements.
return doclint != null && doclint.isGroupEnabled(group, Env.AccessKind.PUBLIC);
return doclint != null && doclint.isGroupEnabled(group, AccessLevel.PUBLIC);
}
//</editor-fold>
}

View File

@ -64,6 +64,7 @@ import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.StringUtils.DamerauLevenshteinDistance;
import jdk.javadoc.internal.tool.AccessLevel;
/**
* Multi-function entry point for the doc check utility.
@ -410,8 +411,8 @@ public class DocLint extends com.sun.tools.doclint.DocLint {
return false;
}
public boolean isGroupEnabled(Messages.Group group, Env.AccessKind accessKind) {
return env.messages.isEnabled(group, accessKind);
public boolean isGroupEnabled(Messages.Group group, AccessLevel accessLevel) {
return env.messages.isEnabled(group, accessLevel);
}
private String localize(String code, Object... args) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,38 +62,13 @@ import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.MatchingUtils;
import com.sun.tools.javac.util.StringUtils;
import jdk.javadoc.internal.tool.AccessLevel;
/**
* Utility container for current execution environment,
* providing the current declaration and its doc comment.
*/
public class Env {
/**
* Access kinds for declarations.
*/
public enum AccessKind {
PRIVATE,
PACKAGE,
PROTECTED,
PUBLIC;
static boolean accepts(String opt) {
for (AccessKind g: values())
if (opt.equals(StringUtils.toLowerCase(g.name()))) return true;
return false;
}
static AccessKind of(Set<Modifier> mods) {
if (mods.contains(Modifier.PUBLIC))
return AccessKind.PUBLIC;
else if (mods.contains(Modifier.PROTECTED))
return AccessKind.PROTECTED;
else if (mods.contains(Modifier.PRIVATE))
return AccessKind.PRIVATE;
else
return AccessKind.PACKAGE;
}
}
/** Message handler. */
final Messages messages;
@ -136,12 +111,12 @@ public class Env {
/** The comment current being analyzed. */
DocCommentTree currDocComment;
/**
* The access kind of the declaration containing the comment currently being analyzed.
* This is the minimum (most restrictive) access kind of the declaration itself
* The access level of the declaration containing the comment currently being analyzed.
* This is the most limiting access level of the declaration itself
* and that of its containers. For example, a public method in a private class is
* noted as private.
*/
AccessKind currAccess;
AccessLevel currAccess;
/** The set of methods, if any, that the current declaration overrides. */
Set<? extends ExecutableElement> currOverriddenMethods;
@ -219,18 +194,18 @@ public class Env {
currElement = trees.getElement(currPath);
currOverriddenMethods = ((JavacTypes) types).getOverriddenMethods(currElement);
AccessKind ak = AccessKind.PUBLIC;
// It's convenient to use AccessLevel to model effects that nesting has
// on access. While very similar, those are not the same concept.
var mostLimitingSoFar = AccessLevel.PUBLIC;
for (TreePath p = path; p != null; p = p.getParentPath()) {
Element e = trees.getElement(p);
if (e != null && e.getKind() != ElementKind.PACKAGE && e.getKind() != ElementKind.MODULE) {
ak = min(ak, AccessKind.of(e.getModifiers()));
var level = AccessLevel.of(e.getModifiers());
mostLimitingSoFar = mostLimitingSoFar.compareTo(level) <= 0
? mostLimitingSoFar : level;
}
}
currAccess = ak;
}
AccessKind getAccessKind() {
return currAccess;
currAccess = mostLimitingSoFar;
}
long getPos(TreePath p) {
@ -359,11 +334,4 @@ public class Env {
}
return List.of();
}
private <T extends Comparable<T>> T min(T item1, T item2) {
return (item1 == null) ? item2
: (item2 == null) ? item1
: item1.compareTo(item2) <= 0 ? item1 : item2;
}
}

View File

@ -43,7 +43,7 @@ import com.sun.source.doctree.DocTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.util.StringUtils;
import jdk.javadoc.internal.doclint.Env.AccessKind;
import jdk.javadoc.internal.tool.AccessLevel;
/**
* Message reporting for DocLint.
@ -109,8 +109,8 @@ public class Messages {
stats.setEnabled(b);
}
boolean isEnabled(Group group, Env.AccessKind ak) {
return options.isEnabled(group, ak);
boolean isEnabled(Group group, AccessLevel al) {
return options.isEnabled(group, al);
}
void reportStats(PrintWriter out) {
@ -176,7 +176,7 @@ public class Messages {
* Handler for (sub)options specific to message handling.
*/
static class Options {
Map<String, Env.AccessKind> map = new HashMap<>();
private final Map<String, AccessLevel> map = new HashMap<>();
private final Stats stats;
static boolean isValidOptions(String opts) {
@ -195,7 +195,13 @@ public class Messages {
int sep = opt.indexOf("/");
String grp = opt.substring(begin, (sep != -1) ? sep : opt.length());
return ((begin == 0 && grp.equals("all")) || Group.accepts(grp))
&& ((sep == -1) || AccessKind.accepts(opt.substring(sep + 1)));
&& ((sep == -1) || accepts(opt.substring(sep + 1)));
}
static boolean accepts(String opt) {
for (var level: AccessLevel.values())
if (opt.equals(StringUtils.toLowerCase(level.name()))) return true;
return false;
}
Options(Stats stats) {
@ -203,19 +209,18 @@ public class Messages {
}
/** Determine if a message group is enabled for a particular access level. */
boolean isEnabled(Group g, Env.AccessKind access) {
boolean isEnabled(Group g, AccessLevel access) {
if (map.isEmpty())
map.put("all", Env.AccessKind.PROTECTED);
map.put(ALL, AccessLevel.PROTECTED);
Env.AccessKind ak = map.get(g.optName());
if (ak != null && access.compareTo(ak) >= 0)
AccessLevel al = map.get(g.optName());
if (al != null && access.compareTo(al) >= 0)
return true;
ak = map.get(ALL);
if (ak != null && access.compareTo(ak) >= 0) {
ak = map.get(g.notOptName());
if (ak == null || access.compareTo(ak) > 0) // note >, not >=
return true;
al = map.get(ALL);
if (al != null && access.compareTo(al) >= 0) {
al = map.get(g.notOptName());
return al == null || access.compareTo(al) > 0; // note >, not >=
}
return false;
@ -223,7 +228,7 @@ public class Messages {
void setOptions(String opts) {
if (opts == null)
setOption(ALL, Env.AccessKind.PRIVATE);
setOption(ALL, AccessLevel.PRIVATE);
else {
for (String opt: opts.split(","))
setOption(StringUtils.toLowerCase(opt.trim()));
@ -238,16 +243,16 @@ public class Messages {
int sep = arg.indexOf("/");
if (sep > 0) {
Env.AccessKind ak = Env.AccessKind.valueOf(StringUtils.toUpperCase(arg.substring(sep + 1)));
setOption(arg.substring(0, sep), ak);
var al = AccessLevel.valueOf(StringUtils.toUpperCase(arg.substring(sep + 1)));
setOption(arg.substring(0, sep), al);
} else {
setOption(arg, null);
}
}
private void setOption(String opt, Env.AccessKind ak) {
map.put(opt, (ak != null) ? ak
: opt.startsWith("-") ? Env.AccessKind.PUBLIC : Env.AccessKind.PRIVATE);
private void setOption(String opt, AccessLevel al) {
map.put(opt, (al != null) ? al
: opt.startsWith("-") ? AccessLevel.PUBLIC : AccessLevel.PRIVATE);
}
private static final String ALL = "all";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,16 +25,40 @@
package jdk.javadoc.internal.tool;
import java.util.Set;
import javax.lang.model.element.Modifier;
/**
* The access value kinds.
* The access levels.
*
* These constants are ordered by their access limiting power. The bigger the
* {@link #ordinal() ordinal} of a constant, the more limiting power that
* constant has.
*
* That has a few useful implications. For example, the levels can be compared
* by {@link #compareTo}. It also means that {@code AccessLevel.values()[0]} and
* {@code AccessLevel.values()[values.length() - 1] and the constants with the
* smallest and the biggest limiting powers respectively.
*/
public enum AccessKind {
/** Limits access to public entities */
PUBLIC,
public enum AccessLevel implements Comparable<AccessLevel> {
/** Does not limit access */
PRIVATE,
/** Limits access to entities that are public, protected, or declared with package access */
PACKAGE,
/** Limits access to public and protected entities */
PROTECTED,
/** Limits access to public, protected and package private entities */
PACKAGE,
/** No limits */
PRIVATE;
/** Limits access to public entities */
PUBLIC;
public static AccessLevel of(Set<Modifier> mods) {
if (mods.contains(Modifier.PUBLIC))
return AccessLevel.PUBLIC;
else if (mods.contains(Modifier.PROTECTED))
return AccessLevel.PROTECTED;
else if (mods.contains(Modifier.PRIVATE))
return AccessLevel.PRIVATE;
else
return AccessLevel.PACKAGE;
}
}

View File

@ -192,7 +192,7 @@ public class ElementsTable {
private final ModifierFilter accessFilter;
private final AccessKind expandRequires;
private final AccessLevel expandRequires;
final boolean xclasses;
@ -605,8 +605,8 @@ public class ElementsTable {
return;
}
final boolean expandAll = expandRequires.equals(AccessKind.PRIVATE)
|| expandRequires.equals(AccessKind.PACKAGE);
final boolean expandAll = expandRequires.equals(AccessLevel.PRIVATE)
|| expandRequires.equals(AccessLevel.PACKAGE);
Set<ModuleElement> result = new LinkedHashSet<>();
ListBuffer<ModuleElement> queue = new ListBuffer<>();
@ -657,13 +657,13 @@ public class ElementsTable {
}
private Set<PackageElement> computeModulePackages() throws ToolException {
AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
AccessLevel accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessLevel.PACKAGE ||
accessValue == AccessLevel.PRIVATE);
accessValue = accessFilter.getAccessValue(ElementKind.MODULE);
final boolean moduleDetailedMode = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
final boolean moduleDetailedMode = (accessValue == AccessLevel.PACKAGE ||
accessValue == AccessLevel.PRIVATE);
Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
for (ModuleElement mdle : specifiedModuleElements) {
@ -1185,12 +1185,8 @@ public class ElementsTable {
ElementKind.PACKAGE,
ElementKind.MODULE);
// all possible access levels allowed for each element
private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
new EnumMap<>(ElementKind.class);
// the specified access level for each element
private final EnumMap<ElementKind, AccessKind> accessMap =
// the allowed access level for each element kind
private final EnumMap<ElementKind, AccessLevel> allowedAccess =
new EnumMap<>(ElementKind.class);
/**
@ -1199,35 +1195,23 @@ public class ElementsTable {
* @param options the tool options
*/
ModifierFilter(ToolOptions options) {
AccessKind accessValue = null;
for (ElementKind kind : ALLOWED_KINDS) {
accessValue = switch (kind) {
var accessValue = switch (kind) {
case METHOD -> options.showMembersAccess();
case CLASS -> options.showTypesAccess();
case PACKAGE -> options.showPackagesAccess();
case MODULE -> options.showModuleContents();
default -> throw new AssertionError("unknown element: " + kind);
};
accessMap.put(kind, accessValue);
filterMap.put(kind, getFilterSet(accessValue));
allowedAccess.put(kind, accessValue);
}
}
static EnumSet<AccessKind> getFilterSet(AccessKind accessValue) {
return switch (accessValue) {
case PUBLIC -> EnumSet.of(AccessKind.PUBLIC);
case PROTECTED -> EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED);
case PACKAGE -> EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED, AccessKind.PACKAGE);
case PRIVATE -> EnumSet.allOf(AccessKind.class);
};
}
public AccessKind getAccessValue(ElementKind kind) {
public AccessLevel getAccessValue(ElementKind kind) {
if (!ALLOWED_KINDS.contains(kind)) {
throw new IllegalArgumentException("not allowed: " + kind);
}
return accessMap.getOrDefault(kind, AccessKind.PROTECTED);
return allowedAccess.getOrDefault(kind, AccessLevel.PROTECTED);
}
/**
@ -1237,21 +1221,13 @@ public class ElementsTable {
* @return whether the modifiers pass this filter
*/
public boolean checkModifier(Element e) {
Set<Modifier> modifiers = e.getModifiers();
AccessKind fflag = AccessKind.PACKAGE;
if (modifiers.contains(Modifier.PUBLIC)) {
fflag = AccessKind.PUBLIC;
} else if (modifiers.contains(Modifier.PROTECTED)) {
fflag = AccessKind.PROTECTED;
} else if (modifiers.contains(Modifier.PRIVATE)) {
fflag = AccessKind.PRIVATE;
}
EnumSet<AccessKind> filterSet = filterMap.get(getAllowedKind(e.getKind()));
return filterSet.contains(fflag);
var access = AccessLevel.of(e.getModifiers());
return allowedAccess.get(toTrackedKind(e.getKind())).compareTo(access) <= 0;
}
// convert a requested element kind to an allowed access kind
private ElementKind getAllowedKind(ElementKind kind) {
// convert the requested element kind to a tracked access kind
// (access is tracked for certain kinds only)
private ElementKind toTrackedKind(ElementKind kind) {
return switch (kind) {
case CLASS, METHOD, MODULE, PACKAGE -> kind;
case RECORD, ANNOTATION_TYPE, ENUM, INTERFACE -> ElementKind.CLASS;

View File

@ -85,7 +85,7 @@ public class ToolOptions {
/**
* Argument for command-line option {@code --expand-requires}.
*/
private AccessKind expandRequires;
private AccessLevel expandRequires;
/**
* Argument for command-line option {@code --ignore-source-errors}.
@ -106,22 +106,22 @@ public class ToolOptions {
/**
* Argument for command-line option {@code --show-members}.
*/
private AccessKind showMembersAccess;
private AccessLevel showMembersAccess;
/**
* Argument for command-line option {@code --show-types}.
*/
private AccessKind showTypesAccess;
private AccessLevel showTypesAccess;
/**
* Argument for command-line option {@code --show-packages}.
*/
private AccessKind showPackagesAccess;
private AccessLevel showPackagesAccess;
/**
* Argument for command-line option {@code --show-module-contents}.
*/
private AccessKind showModuleContents;
private AccessLevel showModuleContents;
/**
* Argument for command-line option {@code -quiet}.
@ -717,7 +717,7 @@ public class ToolOptions {
/**
* Argument for command-line option {@code --expand-requires}.
*/
AccessKind expandRequires() {
AccessLevel expandRequires() {
return expandRequires;
}
@ -746,28 +746,28 @@ public class ToolOptions {
/**
* Argument for command-line option {@code --show-members}.
*/
AccessKind showMembersAccess() {
AccessLevel showMembersAccess() {
return showMembersAccess;
}
/**
* Argument for command-line option {@code --show-types}.
*/
AccessKind showTypesAccess() {
AccessLevel showTypesAccess() {
return showTypesAccess;
}
/**
* Argument for command-line option {@code --show-packages}.
*/
AccessKind showPackagesAccess() {
AccessLevel showPackagesAccess() {
return showPackagesAccess;
}
/**
* Argument for command-line option {@code --show-module-contents}.
*/
AccessKind showModuleContents() {
AccessLevel showModuleContents() {
return showModuleContents;
}
@ -885,40 +885,25 @@ public class ToolOptions {
private void setExpandRequires(String arg) throws OptionException {
switch (arg) {
case "transitive":
expandRequires = AccessKind.PUBLIC;
break;
case "all":
expandRequires = AccessKind.PRIVATE;
break;
default:
throw illegalOptionValue(arg);
case "transitive" -> expandRequires = AccessLevel.PUBLIC;
case "all" -> expandRequires = AccessLevel.PRIVATE;
default -> throw illegalOptionValue(arg);
}
}
private void setShowModuleContents(String arg) throws OptionException {
switch (arg) {
case "api":
showModuleContents = AccessKind.PUBLIC;
break;
case "all":
showModuleContents = AccessKind.PRIVATE;
break;
default:
throw illegalOptionValue(arg);
case "api" -> showModuleContents = AccessLevel.PUBLIC;
case "all" -> showModuleContents = AccessLevel.PRIVATE;
default -> throw illegalOptionValue(arg);
}
}
private void setShowPackageAccess(String arg) throws OptionException {
switch (arg) {
case "exported":
showPackagesAccess = AccessKind.PUBLIC;
break;
case "all":
showPackagesAccess = AccessKind.PRIVATE;
break;
default:
throw illegalOptionValue(arg);
case "exported" -> showPackagesAccess = AccessLevel.PUBLIC;
case "all" -> showPackagesAccess = AccessLevel.PRIVATE;
default -> throw illegalOptionValue(arg);
}
}
@ -948,53 +933,37 @@ public class ToolOptions {
* -private, so on, in addition to the new ones such as
* --show-types:public and so on.
*/
private AccessKind getAccessValue(String arg) throws OptionException {
private AccessLevel getAccessValue(String arg) throws OptionException {
int colon = arg.indexOf(':');
String value = (colon > 0)
? arg.substring(colon + 1)
: arg;
switch (value) {
case "public":
return AccessKind.PUBLIC;
case "protected":
return AccessKind.PROTECTED;
case "package":
return AccessKind.PACKAGE;
case "private":
return AccessKind.PRIVATE;
default:
throw illegalOptionValue(value);
}
String value = (colon > 0) ? arg.substring(colon + 1) : arg;
return switch (value) {
case "public" -> AccessLevel.PUBLIC;
case "protected" -> AccessLevel.PROTECTED;
case "package" -> AccessLevel.PACKAGE;
case "private" -> AccessLevel.PRIVATE;
default -> throw illegalOptionValue(value);
};
}
/*
* Sets all access members to PROTECTED; this is the default.
*/
private void setAccessDefault() {
setAccess(AccessKind.PROTECTED);
setAccess(AccessLevel.PROTECTED);
}
/*
* This sets access to all the allowed kinds in the
* Sets access level to all the allowed kinds in the
* access members.
*/
private void setAccess(AccessKind accessValue) {
private void setAccess(AccessLevel accessValue) {
for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
switch (kind) {
case METHOD:
showMembersAccess = accessValue;
break;
case CLASS:
showTypesAccess = accessValue;
break;
case PACKAGE:
showPackagesAccess = accessValue;
break;
case MODULE:
showModuleContents = accessValue;
break;
default:
throw new AssertionError("unknown element kind:" + kind);
case METHOD -> showMembersAccess = accessValue;
case CLASS -> showTypesAccess = accessValue;
case PACKAGE -> showPackagesAccess = accessValue;
case MODULE -> showModuleContents = accessValue;
default -> throw new AssertionError("unknown element kind:" + kind);
}
}
}