diff --git a/README.md b/README.md index cf18b2d..2acce4c 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,12 @@ incomplete or incorrect, please [open an issue](https://github.com/Saxonica/xmld ## Change log +* **0.9.0** Fixed package and type names; fixed interface lists + + Package and type names are correct (fixed [#10](https://github.com/Saxonica/xmldoclet/issues/10)), + and the interfaces of supertypes are included in the list of implemented interfaces + (fixed [#11](https://github.com/Saxonica/xmldoclet/issues/11)). + * **0.8.0** Fixed method names Output the “simple” method name in the name attribute on method elements. diff --git a/gradle.properties b/gradle.properties index be67956..5d1b87e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -docletVersion=0.8.0 -schemaVersion=0.8.0 +docletVersion=0.9.0 +schemaVersion=0.9.0 docletTitle=XmlDoclet docletName=xmldoclet diff --git a/sample/src/main/java/org/example/ClassWithNested.java b/sample/src/main/java/org/example/ClassWithNested.java new file mode 100644 index 0000000..338fe23 --- /dev/null +++ b/sample/src/main/java/org/example/ClassWithNested.java @@ -0,0 +1,25 @@ +package org.example; + +public abstract class ClassWithNested implements InterfaceA, InterfaceB { + /** + * Something goes here + * @return true + */ + public boolean isSomething() { + return true; + } + + public abstract static class Nested extends ClassWithNested implements InterfaceAB { + protected T[] items; + public Nested(T[] items) { + this.items = items; + } + public void a() {} + + public static class DoublyNested extends ClassWithNested { + public DoublyNested() {} + public void a() {} + public void b() {} + } + } +} diff --git a/sample/src/main/java/org/example/InterfaceB.java b/sample/src/main/java/org/example/InterfaceB.java new file mode 100644 index 0000000..32c419d --- /dev/null +++ b/sample/src/main/java/org/example/InterfaceB.java @@ -0,0 +1,5 @@ +package org.example; + +public interface InterfaceB { + void b(); +} diff --git a/xmldoclet/src/main/java/com/saxonica/xmldoclet/scanners/XmlTypeElement.java b/xmldoclet/src/main/java/com/saxonica/xmldoclet/scanners/XmlTypeElement.java index c75a440..73ee6b9 100644 --- a/xmldoclet/src/main/java/com/saxonica/xmldoclet/scanners/XmlTypeElement.java +++ b/xmldoclet/src/main/java/com/saxonica/xmldoclet/scanners/XmlTypeElement.java @@ -24,10 +24,13 @@ public XmlTypeElement(XmlProcessor xmlproc, TypeElement element) { public void scan(DocTree tree) { String s = element.getQualifiedName().toString(); + String pkgName = getPackage(element); + String typeName = getType(element); + Map attr = new HashMap<>(); attr.put("fullname", element.getQualifiedName().toString()); - attr.put("package", element.getEnclosingElement().toString()); - attr.put("type", element.getSimpleName().toString()); + attr.put("package", pkgName); + attr.put("type", typeName); attr.put("nesting", element.getNestingKind().toString().toLowerCase()); attr.putAll(modifierAttributes(element)); @@ -42,9 +45,10 @@ public void scan(DocTree tree) { showSuperclass(element, (DeclaredType) element.getSuperclass(), impl); } - if (!element.getInterfaces().isEmpty()) { + List interfaces = getInterfaces(element); + if (!interfaces.isEmpty()) { builder.startElement("interfaces"); - for (TypeMirror tm : element.getInterfaces()) { + for (TypeMirror tm : interfaces) { // Reset the implemented list each time Implemented classimpl = new Implemented(impl); updateImplemented(element, classimpl); @@ -79,6 +83,62 @@ public void scan(DocTree tree) { builder.endElement(typeName()); } + /** + * Find the element's package. + *

For nested classes, we may have to look up several times.

+ * @return the package name + */ + private String getPackage(Element element) { + Element enclosing = element.getEnclosingElement(); + + if (enclosing == null) { + return ""; + } + + if (enclosing instanceof PackageElement) { + return enclosing.toString(); + } + + return getPackage(enclosing); + } + + /** + * Find the name of this type; that's our ancestor names if this is a nested class. + * @param element The element + * @return The type name + */ + private String getType(Element element) { + Element enclosing = element.getEnclosingElement(); + if (enclosing instanceof TypeElement) { + String stype = getType(enclosing); + if (!"".equals(stype)) { + return stype + "." + element.getSimpleName().toString(); + } + return element.getSimpleName().toString(); + } + return element.getSimpleName().toString(); + } + + /** + * Find the implemented interfaces + *

This includes the interfaces of any classes we extend.

+ * @param element the starting element + * @return list of interfaces + */ + private List getInterfaces(TypeElement element) { + List interfaces = new ArrayList<>(element.getInterfaces()); + + TypeMirror superClass = element.getSuperclass(); + if (superClass instanceof DeclaredType) { + Element superElem = ((DeclaredType) superClass).asElement(); + if (superElem instanceof TypeElement) { + interfaces.addAll(getInterfaces((TypeElement) superElem)); + } + } + + return interfaces; + } + private void showSuperclass(TypeElement element, DeclaredType superclass, Implemented impl) { if ("java.lang.Object".equals(superclass.toString())) { return;