--- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java 2019-10-30 16:24:21.223747365 -0700 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java 2019-10-30 16:24:20.851747378 -0700 @@ -47,6 +47,7 @@ import javax.lang.model.element.ModuleElement; import javax.lang.model.element.ModuleElement.RequiresDirective; import javax.lang.model.element.PackageElement; +import javax.lang.model.element.RecordComponentElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; @@ -60,9 +61,9 @@ import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.ElementKindVisitor9; +import javax.lang.model.util.ElementKindVisitor14; import javax.lang.model.util.Elements; -import javax.lang.model.util.SimpleElementVisitor9; +import javax.lang.model.util.SimpleElementVisitor14; import javax.lang.model.util.SimpleTypeVisitor9; import javax.lang.model.util.TypeKindVisitor9; import javax.lang.model.util.Types; @@ -301,8 +302,9 @@ return !e.getAnnotationMirrors().isEmpty(); } + @SuppressWarnings("preview") public boolean isAnnotationType(Element e) { - return new SimpleElementVisitor9() { + return new SimpleElementVisitor14() { @Override public Boolean visitExecutable(ExecutableElement e, Void p) { return visit(e.getEnclosingElement()); @@ -416,6 +418,34 @@ return typeUtils.isSubtype(e.asType(), getExternalizableType()); } + @SuppressWarnings("preview") + public boolean isRecord(TypeElement e) { + return e.getKind() == ElementKind.RECORD; + } + + @SuppressWarnings("preview") + public boolean isCanonicalRecordConstructor(ExecutableElement ee) { + TypeElement te = (TypeElement) ee.getEnclosingElement(); + List stateComps = te.getRecordComponents(); + List params = ee.getParameters(); + if (stateComps.size() != params.size()) { + return false; + } + + Iterator stateIter = stateComps.iterator(); + Iterator paramIter = params.iterator(); + while (paramIter.hasNext() && stateIter.hasNext()) { + VariableElement param = paramIter.next(); + RecordComponentElement comp = stateIter.next(); + if (!Objects.equals(param.getSimpleName(), comp.getSimpleName()) + || !typeUtils.isSameType(param.asType(), comp.asType())) { + return false; + } + } + + return true; + } + public SortedSet serializableFields(TypeElement aclass) { return configuration.workArounds.getSerializableFields(aclass); } @@ -428,85 +458,102 @@ return configuration.workArounds.definesSerializableFields( aclass); } + @SuppressWarnings("preview") public String modifiersToString(Element e, boolean trailingSpace) { - SortedSet set = new TreeSet<>(e.getModifiers()); - set.remove(Modifier.NATIVE); - set.remove(Modifier.STRICTFP); - set.remove(Modifier.SYNCHRONIZED); + SortedSet modifiers = new TreeSet<>(e.getModifiers()); + modifiers.remove(NATIVE); + modifiers.remove(STRICTFP); + modifiers.remove(SYNCHRONIZED); - return new ElementKindVisitor9>() { + return new ElementKindVisitor14>() { final StringBuilder sb = new StringBuilder(); void addVisibilityModifier(Set modifiers) { if (modifiers.contains(PUBLIC)) { - sb.append("public").append(" "); + append("public"); } else if (modifiers.contains(PROTECTED)) { - sb.append("protected").append(" "); + append("protected"); } else if (modifiers.contains(PRIVATE)) { - sb.append("private").append(" "); + append("private"); } } void addStatic(Set modifiers) { if (modifiers.contains(STATIC)) { - sb.append("static").append(" "); + append("static"); } } - void addModifers(Set modifiers) { - String s = set.stream().map(Modifier::toString).collect(Collectors.joining(" ")); - sb.append(s); - if (!s.isEmpty()) + void addModifiers(Set modifiers) { + modifiers.stream().map(Modifier::toString).forEach(this::append); + } + + void append(String s) { + if (sb.length() > 0) { sb.append(" "); + } + sb.append(s); } String finalString(String s) { - sb.append(s); + append(s); if (trailingSpace) { - if (sb.lastIndexOf(" ") == sb.length() - 1) { - return sb.toString(); - } else { - return sb.append(" ").toString(); + sb.append(" "); } - } else { - return sb.toString().trim(); - } + return sb.toString(); } @Override - public String visitTypeAsInterface(TypeElement e, SortedSet p) { - addVisibilityModifier(p); - addStatic(p); + public String visitTypeAsInterface(TypeElement e, SortedSet mods) { + addVisibilityModifier(mods); + addStatic(mods); return finalString("interface"); } @Override - public String visitTypeAsEnum(TypeElement e, SortedSet p) { - addVisibilityModifier(p); - addStatic(p); + public String visitTypeAsEnum(TypeElement e, SortedSet mods) { + addVisibilityModifier(mods); + addStatic(mods); return finalString("enum"); } @Override - public String visitTypeAsAnnotationType(TypeElement e, SortedSet p) { - addVisibilityModifier(p); - addStatic(p); + public String visitTypeAsAnnotationType(TypeElement e, SortedSet mods) { + addVisibilityModifier(mods); + addStatic(mods); return finalString("@interface"); } @Override - public String visitTypeAsClass(TypeElement e, SortedSet p) { - addModifers(p); - return finalString("class"); + public String visitTypeAsRecord(TypeElement e, SortedSet mods) { + mods.remove(FINAL); // suppress the implicit `final` + return visitTypeAsClass(e, mods); + } + + @Override + @SuppressWarnings("preview") + public String visitTypeAsClass(TypeElement e, SortedSet mods) { + Set beforeSealed = EnumSet.noneOf(Modifier.class); + Set afterSealed = EnumSet.noneOf(Modifier.class); + Set set = beforeSealed; + for (Modifier m : Modifier.values()) { + if (mods.contains(m)) { + set.add(m); + } + } + addModifiers(beforeSealed); + addModifiers(afterSealed); + String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class"; + return finalString(keyword); } @Override - protected String defaultAction(Element e, SortedSet p) { - addModifers(p); + protected String defaultAction(Element e, SortedSet mods) { + addModifiers(mods); return sb.toString().trim(); } - }.visit(e, set); + }.visit(e, modifiers); } public boolean isFunctionalInterface(AnnotationMirror amirror) { @@ -593,7 +640,7 @@ public boolean isTypeElement(Element e) { switch (e.getKind()) { - case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: + case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: case RECORD: return true; default: return false; @@ -1363,27 +1410,6 @@ } /** - * The documentation for values() and valueOf() in Enums are set by the - * doclet only iff the user or overridden methods are missing. - * @param elem - */ - public void setEnumDocumentation(TypeElement elem) { - for (Element e : getMethods(elem)) { - ExecutableElement ee = (ExecutableElement)e; - if (!getFullBody(e).isEmpty()) // ignore if already set - continue; - if (ee.getSimpleName().contentEquals("values") && ee.getParameters().isEmpty()) { - removeCommentHelper(ee); // purge previous entry - configuration.cmtUtils.setEnumValuesTree(e); - } - if (ee.getSimpleName().contentEquals("valueOf") && ee.getParameters().size() == 1) { - removeCommentHelper(ee); // purge previous entry - configuration.cmtUtils.setEnumValueOfTree(e); - } - } - } - - /** * Returns a locale independent upper cased String. That is, it * always uses US locale, this is a clone of the one in StringUtils. * @param s to convert @@ -1760,7 +1786,7 @@ result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2)); if (result != 0) return result; - return compareElementTypeKinds(o1, o2); + return compareElementKinds(o1, o2); } }; } @@ -1809,7 +1835,7 @@ return result; } // if names are the same, compare element kinds - result = compareElementTypeKinds(e1, e2); + result = compareElementKinds(e1, e2); if (result != 0) { return result; } @@ -1917,8 +1943,9 @@ return getFullyQualifiedName(e, true); } + @SuppressWarnings("preview") public String getFullyQualifiedName(Element e, final boolean outer) { - return new SimpleElementVisitor9() { + return new SimpleElementVisitor14() { @Override public String visitModule(ModuleElement e, Void p) { return e.getQualifiedName().toString(); @@ -1985,7 +2012,7 @@ if (result != 0) { return result; } - return compareElementTypeKinds(e1, e2); + return compareElementKinds(e1, e2); } }; } @@ -1997,6 +2024,8 @@ * for creating specific comparators for an use-case. */ private abstract class ElementComparator implements Comparator { + public ElementComparator() { } + /** * compares two parameter arrays by first comparing the length of the arrays, and * then each Type of the parameter in the array. @@ -2005,21 +2034,6 @@ * @return a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. */ - final EnumMap elementKindOrder; - public ElementComparator() { - elementKindOrder = new EnumMap<>(ElementKind.class); - elementKindOrder.put(ElementKind.MODULE, 0); - elementKindOrder.put(ElementKind.PACKAGE, 1); - elementKindOrder.put(ElementKind.CLASS, 2); - elementKindOrder.put(ElementKind.ENUM, 3); - elementKindOrder.put(ElementKind.ENUM_CONSTANT, 4); - elementKindOrder.put(ElementKind.INTERFACE, 5); - elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 6); - elementKindOrder.put(ElementKind.FIELD, 7); - elementKindOrder.put(ElementKind.CONSTRUCTOR, 8); - elementKindOrder.put(ElementKind.METHOD, 9); - } - protected int compareParameters(boolean caseSensitive, List params1, List params2) { @@ -2082,12 +2096,31 @@ String thatElement = getFullyQualifiedName(e2); return compareStrings(thisElement, thatElement); } - protected int compareElementTypeKinds(Element e1, Element e2) { - return Integer.compare(elementKindOrder.get(e1.getKind()), - elementKindOrder.get(e2.getKind())); + + protected int compareElementKinds(Element e1, Element e2) { + return Integer.compare(getKindIndex(e1), getKindIndex(e2)); + } + + private int getKindIndex(Element e) { + switch (e.getKind()) { + case MODULE: return 0; + case PACKAGE: return 1; + case CLASS: return 2; + case ENUM: return 3; + case ENUM_CONSTANT: return 4; + case RECORD: return 5; + case INTERFACE: return 6; + case ANNOTATION_TYPE: return 7; + case FIELD: return 8; + case CONSTRUCTOR: return 9; + case METHOD: return 10; + default: throw new IllegalArgumentException(e.getKind().toString()); + } } + + @SuppressWarnings("preview") boolean hasParameters(Element e) { - return new SimpleElementVisitor9() { + return new SimpleElementVisitor14() { @Override public Boolean visitExecutable(ExecutableElement e, Void p) { return true; @@ -2107,8 +2140,9 @@ * @return a negative integer, zero, or a positive integer as the first argument is less * than, equal to, or greater than the second. */ + @SuppressWarnings("preview") private String getFullyQualifiedName(Element e) { - return new SimpleElementVisitor9() { + return new SimpleElementVisitor14() { @Override public String visitModule(ModuleElement e, Void p) { return e.getQualifiedName().toString(); @@ -2187,6 +2221,7 @@ out.addAll(getClasses(pkg)); out.addAll(getEnums(pkg)); out.addAll(getAnnotationTypes(pkg)); + out.addAll(getRecords(pkg)); return out; } @@ -2217,6 +2252,16 @@ return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE)); } + @SuppressWarnings("preview") + public List getRecords(Element e) { + return convertToTypeElement(getItems(e, true, RECORD)); + } + + @SuppressWarnings("preview") + public List getRecordsUnfiltered(Element e) { + return convertToTypeElement(getItems(e, false, RECORD)); + } + public List getFields(Element e) { return convertToVariableElement(getItems(e, true, FIELD)); } @@ -2371,6 +2416,7 @@ List clist = getClassesUnfiltered(e); clist.addAll(getInterfacesUnfiltered(e)); clist.addAll(getAnnotationTypesUnfiltered(e)); + clist.addAll(getRecordsUnfiltered(e)); SortedSet oset = new TreeSet<>(makeGeneralPurposeComparator()); oset.addAll(clist); return oset; @@ -2391,6 +2437,7 @@ clist.addAll(getInterfaces(e)); clist.addAll(getAnnotationTypes(e)); clist.addAll(getEnums(e)); + clist.addAll(getRecords(e)); oset = new TreeSet<>(makeGeneralPurposeComparator()); oset.addAll(clist); cachedClasses.put(e, oset); @@ -2459,9 +2506,10 @@ .collect(Collectors.toList()); } + @SuppressWarnings("preview") List getItems(Element e, boolean filter, ElementKind select) { List elements = new ArrayList<>(); - return new SimpleElementVisitor9, Void>() { + return new SimpleElementVisitor14, Void>() { @Override public List visitPackage(PackageElement e, Void p) { @@ -2506,11 +2554,13 @@ return elements; } - private SimpleElementVisitor9 shouldDocumentVisitor = null; + @SuppressWarnings("preview") + private SimpleElementVisitor14 shouldDocumentVisitor = null; - protected boolean shouldDocument(Element e) { + @SuppressWarnings("preview") + public boolean shouldDocument(Element e) { if (shouldDocumentVisitor == null) { - shouldDocumentVisitor = new SimpleElementVisitor9() { + shouldDocumentVisitor = new SimpleElementVisitor14() { private boolean hasSource(TypeElement e) { return configuration.docEnv.getFileKind(e) == javax.tools.JavaFileObject.Kind.SOURCE; @@ -2560,11 +2610,13 @@ return nameCache.computeIfAbsent(e, this::getSimpleName0); } - private SimpleElementVisitor9 snvisitor = null; + @SuppressWarnings("preview") + private SimpleElementVisitor14 snvisitor = null; + @SuppressWarnings("preview") private String getSimpleName0(Element e) { if (snvisitor == null) { - snvisitor = new SimpleElementVisitor9() { + snvisitor = new SimpleElementVisitor14() { @Override public String visitModule(ModuleElement e, Void p) { return e.getQualifiedName().toString(); // temp fix for 8182736 @@ -2745,10 +2797,12 @@ return configuration.docEnv.isIncluded(e); } - private SimpleElementVisitor9 specifiedVisitor = null; + @SuppressWarnings("preview") + private SimpleElementVisitor14 specifiedVisitor = null; + @SuppressWarnings("preview") public boolean isSpecified(Element e) { if (specifiedVisitor == null) { - specifiedVisitor = new SimpleElementVisitor9() { + specifiedVisitor = new SimpleElementVisitor14() { @Override public Boolean visitModule(ModuleElement e, Void p) { return configuration.getSpecifiedModuleElements().contains(e); @@ -3196,20 +3250,20 @@ return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS); } - public List getTypeParamTrees(Element element) { + public List getTypeParamTrees(Element element) { return getParamTrees(element, true); } - public List getParamTrees(Element element) { + public List getParamTrees(Element element) { return getParamTrees(element, false); } - private List getParamTrees(Element element, boolean isTypeParameters) { - List out = new ArrayList<>(); + private List getParamTrees(Element element, boolean isTypeParameters) { + List out = new ArrayList<>(); for (DocTree dt : getBlockTags(element, PARAM)) { ParamTree pt = (ParamTree) dt; if (pt.isTypeParameter() == isTypeParameters) { - out.add(dt); + out.add(pt); } } return out;