Skip to content

Commit

Permalink
Merge pull request #8 from Saxonica/interfaces
Browse files Browse the repository at this point in the history
Rework how interfaces are displayed
  • Loading branch information
ndw authored Sep 19, 2024
2 parents 647ce61 + 8cc2648 commit c4fe46f
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 37 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ incomplete or incorrect, please [open an issue](https://github.com/Saxonica/xmld

## Change log

* **0.7.0** Improved presentation of interfaces

Reworked the way interfaces are presented so that the methods inherited
from those interfaces (i.e., the methods not actually implemented on this class)
are shown.

* **0.6.0** Improved handling of method names and inheritance

Changed the “name” of methods to include the parameter types. (i.e., `foo(int)`
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
docletVersion=0.6.0
schemaVersion=0.6.0
docletVersion=0.7.0
schemaVersion=0.7.0
docletTitle=XmlDoclet
docletName=xmldoclet
4 changes: 4 additions & 0 deletions sample/src/main/java/org/example/Impl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.example;

abstract public class Impl implements InterfaceAB, InterfaceA {
}
8 changes: 8 additions & 0 deletions sample/src/main/java/org/example/ImplAB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example;

abstract public class ImplAB implements InterfaceAB {
@Override
public void a() {
System.err.println("ImplAB implements a");
}
}
13 changes: 13 additions & 0 deletions sample/src/main/java/org/example/ImplABC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example;

public class ImplABC extends ImplAB implements InterfaceABC {
@Override
public void b() {
System.err.println("ImplABC implements b");
}

@Override
public void c() {
System.err.println("ImplABC implements c");
}
}
5 changes: 5 additions & 0 deletions sample/src/main/java/org/example/InterfaceA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.example;

public interface InterfaceA {
void a();
}
5 changes: 5 additions & 0 deletions sample/src/main/java/org/example/InterfaceAB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.example;

public interface InterfaceAB extends InterfaceA {
void b();
}
5 changes: 5 additions & 0 deletions sample/src/main/java/org/example/InterfaceABC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.example;

public interface InterfaceABC extends InterfaceAB {
void c();
}
1 change: 0 additions & 1 deletion sample/src/main/java/org/example/IterImpl.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.example;

public class IterImpl implements SequenceIterator {
@Override
public boolean hasNext() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,20 @@ public void scan(DocTree tree) {

builder.startElement(typeName(), attr);

Implemented impl = new Implemented();
updateImplemented(element, impl);

if (element.getSuperclass() instanceof DeclaredType) {
Implemented impl = new Implemented();
updateImplemented(element, impl);
showSuperclass(element, (DeclaredType) element.getSuperclass(), impl);
}

if (!element.getInterfaces().isEmpty()) {
builder.startElement("interfaces");
for (TypeMirror tm : element.getInterfaces()) {
TypeUtils.xmlType(builder, "interfaceref", tm);
// Reset the implemented list each time
Implemented classimpl = new Implemented(impl);
updateImplemented(element, classimpl);
showInterfaces(element, (DeclaredType) tm, impl);
}
builder.endElement("interfaces");
}
Expand Down Expand Up @@ -76,15 +80,20 @@ public void scan(DocTree tree) {
}

private void showSuperclass(TypeElement element, DeclaredType superclass, Implemented impl) {
if ("java.lang.Object".equals(superclass.toString())) {
return;
}
/*
if (element.getSuperclass() instanceof DeclaredType) {
String name = ((DeclaredType) element.getSuperclass()).toString();
if ("java.lang.Object".equals(name)) {
return;
}
}
*/

builder.startElement("superclass");
TypeUtils.xmlType(builder, "type", element.getSuperclass());
TypeUtils.xmlType(builder, "type", superclass);

List<? extends Element> enclosed = superclass.asElement().getEnclosedElements();

Expand Down Expand Up @@ -128,7 +137,7 @@ private void showSuperclass(TypeElement element, DeclaredType superclass, Implem
TypeElement setype = (TypeElement) selem;
TypeMirror sstype = setype.getSuperclass();

showInterfaces(setype, impl);
//showInterfaces(setype, impl);

if (sstype.getKind() == TypeKind.DECLARED) {
showSuperclass(setype, (DeclaredType) sstype, impl);
Expand All @@ -139,44 +148,68 @@ private void showSuperclass(TypeElement element, DeclaredType superclass, Implem
builder.endElement("superclass");
}

private void showInterfaces(TypeElement element, Implemented impl) {
if (element.getInterfaces().isEmpty()) {
return;
private void showInterfaces(TypeElement element, DeclaredType xinter, Implemented impl) {
Map<String, String> attr = new HashMap<>();
attr.put("name", xinter.asElement().getSimpleName().toString());
attr.put("fullname", xinter.asElement().toString());
attr.put("package", xinter.asElement().getEnclosingElement().toString());
builder.startElement("interface", attr);

for (TypeMirror tm : xinter.getTypeArguments()) {
attr.clear();
TypeUtils.xmlType(builder, "param", tm);
}

for (TypeMirror tm : element.getInterfaces()) {
if (tm.getKind() == TypeKind.DECLARED) {
TypeElement ttm = (TypeElement) ((DeclaredType) tm).asElement();
Map<String, String> amap = new HashMap<>();
amap.put("fullname", ttm.toString());
amap.put("name", ttm.getSimpleName().toString());
if (ttm.toString().contains(".")) {
amap.put("package", ttm.toString().substring(0, ttm.toString().lastIndexOf(".")));
}

builder.startElement("interface", amap);
List<? extends Element> enclosed = xinter.asElement().getEnclosedElements();

for (Element celem : ttm.getEnclosedElements()) {
if (celem.getKind() == ElementKind.FIELD) {
amap = new HashMap<>();
amap.put("name", celem.getSimpleName().toString());
builder.startElement("field", amap);
builder.endElement("field");
List<Element> inherited = new ArrayList<>();
for (Element elem : enclosed) {
String name = elem.toString();
if (!elem.getModifiers().contains(Modifier.PRIVATE)) {
if (elem.getKind() == ElementKind.FIELD) {
if (!impl.fields.contains(name)) {
impl.fields.add(name);
inherited.add(elem);
}
if (celem.getKind() == ElementKind.METHOD) {
if (!impl.methods.contains(celem.toString())) {
amap = new HashMap<>();
amap.put("name", celem.toString());
builder.startElement("method", amap);
builder.endElement("method");
}
}
if (elem.getKind() == ElementKind.METHOD) {
if (!impl.methods.contains(name)) {
impl.methods.add(name);
inherited.add(elem);
}
}
}
}

if (!inherited.isEmpty()) {
builder.startElement("inherited");
for (Element elem : inherited) {
Map<String, String> amap = new HashMap<>();
amap.put("name", elem.toString());
if (elem.getKind() == ElementKind.FIELD) {
builder.startElement("field", amap);
builder.endElement("field");
} else {
builder.startElement("method", amap);
builder.endElement("method");
}
}
builder.endElement("inherited");
}

showInterfaces(ttm, impl);
builder.endElement("interface");
Element selem = xinter.asElement();
if (selem instanceof TypeElement) {
TypeElement setype = (TypeElement) selem;
TypeMirror sstype = setype.getSuperclass();

if (!setype.getInterfaces().isEmpty()) {
for (TypeMirror tm : setype.getInterfaces()) {
showInterfaces(element, (DeclaredType) tm, impl);
}
}
}

builder.endElement("interface");
}

private void updateImplemented(TypeElement element, Implemented impl) {
Expand All @@ -195,6 +228,11 @@ private void updateImplemented(TypeElement element, Implemented impl) {
}

private static class Implemented {
public Implemented() {}
public Implemented(Implemented impl) {
fields.addAll(impl.fields);
methods.addAll(impl.methods);
}
public final Set<String> fields = new HashSet<>();
public final Set<String> methods = new HashSet<>();
}
Expand Down

0 comments on commit c4fe46f

Please sign in to comment.