diff --git a/src/main/jastadd/ToJson.jrag b/src/main/jastadd/ToJson.jrag index a67880bab7348ef12ebe80ea8ab267d7726d4dda..82482270d7507dd61da409497c81bc0e6fb2bfba 100644 --- a/src/main/jastadd/ToJson.jrag +++ b/src/main/jastadd/ToJson.jrag @@ -100,6 +100,8 @@ aspect ToJson { JsonObject doc = jsonDocObject(); if (doc != null && !doc.get("attribute").stringValue("").isEmpty()) { return "attr"; + } else if (doc != null && !doc.get("relation").stringValue("").isEmpty()) { + return "rel"; } else { return "method"; } diff --git a/src/main/java/org/extendj/ragdoc/JavaDocParser.java b/src/main/java/org/extendj/ragdoc/JavaDocParser.java index 5111ce1ce418bb9787688f8d83a14c89ff29ad73..31178fcde688b758f94f203029ec69dd34cc5b97 100644 --- a/src/main/java/org/extendj/ragdoc/JavaDocParser.java +++ b/src/main/java/org/extendj/ragdoc/JavaDocParser.java @@ -117,6 +117,7 @@ public class JavaDocParser extends Object { tag.equals("astdecl") || tag.equals("ast") || tag.equals("aspect") || tag.equals("apilevel") || tag.equals("attribute") || + tag.equals("relation") || /* JavaDoc tags: * (http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadoctags) */ diff --git a/src/main/java/org/extendj/ragdoc/JsonBuilder.java b/src/main/java/org/extendj/ragdoc/JsonBuilder.java index d59c8dee259d4d75179eb464d152bb672fef97f9..07f98502c9d029c9bfe2c6228d49e9c0072a672c 100644 --- a/src/main/java/org/extendj/ragdoc/JsonBuilder.java +++ b/src/main/java/org/extendj/ragdoc/JsonBuilder.java @@ -29,6 +29,7 @@ */ package org.extendj.ragdoc; +import org.extendj.ast.*; import org.extendj.ast.Access; import org.extendj.ast.BodyDecl; import org.extendj.ast.ClassDecl; @@ -39,7 +40,9 @@ import org.extendj.ast.FieldDecl; import org.extendj.ast.InterfaceDecl; import org.extendj.ast.MethodDecl; import org.extendj.ast.ParameterDeclaration; +import org.extendj.ast.SimpleSet; import org.extendj.ast.TypeDecl; +import org.extendj.ast.UnknownType; import org.extendj.ast.Variable; import org.extendj.util.RelativePath; import org.extendj.util.Sorting; @@ -72,7 +75,7 @@ public class JsonBuilder { /** Ordering of the package object kinds. */ private static final String[] TYPE_KINDS = { "ast-class", "interface", "class" }; - private static final String[] MEMBER_KINDS = { "constr", "attr", "field", "method" }; + private static final String[] MEMBER_KINDS = { "constr", "attr", "rel", "field", "method" }; private final File rootDir; private java.util.List<String> ragRoot = new java.util.LinkedList<>(); @@ -130,6 +133,8 @@ public class JsonBuilder { public void addMethod(MethodDecl method, JsonArray members) { JsonObject doc = method.jsonDocObject(); + // System.out.println("" + method.type() + ": " + method + ", kind=" + method.objectKind()); + // System.out.println("`-> doc=" + doc + " doc.get(relation)=" + (doc != null ? doc.get("relation") : "/")); if (shouldDocument(method, doc)) { JsonObject obj = new JsonObject(); obj.add("name", Json.of(method.name())); @@ -394,7 +399,8 @@ public class JsonBuilder { // Create declaration structure. JsonObject decl = parser.parse(); if (!decl.get("e").stringValue("").isEmpty()) { - decl.set("e", typeRef(type.lookupType(decl.get("e").stringValue("")).singletonValue())); + decl.set("e", + typeRef(safeLookupType(type, decl.get("e").stringValue("")).singletonValue())); } doc.set("astdecl", decl); JsonArray array = decl.get("c").array(); @@ -402,7 +408,7 @@ public class JsonBuilder { JsonObject comp = c.object(); if (!comp.get("e").stringValue("").isEmpty()) { comp.set("e", - typeRef(type.lookupType(stripGenericPart(comp.get("e").stringValue(""))).singletonValue())); + typeRef(safeLookupType(type, stripGenericPart(comp.get("e").stringValue(""))))); } } } catch (IOException e) { @@ -433,6 +439,15 @@ public class JsonBuilder { return obj; } + private TypeDecl safeLookupType(TypeDecl parent, String name) { + SimpleSet<TypeDecl> types = parent.lookupType(name); + if (types.isEmpty()) { + System.err.println("Could not find type for '" + name + "'"); + return parent.unknownType(); + } + return types.singletonValue(); + } + private String stripGenericPart(String s) { int ltIndex = s.indexOf('<'); return ltIndex == -1 ? s : s.substring(0, ltIndex); @@ -455,8 +470,10 @@ public class JsonBuilder { * Adds inherited members from superclasses. */ private void addInheritedMembers(TypeDecl type, JsonObject obj) { + // TODO (rs): Add inherited relations if (type instanceof ClassDecl) { JsonArray inheritedMethods = new JsonArray(); + JsonArray inheritedRelations = new JsonArray(); JsonArray inheritedAttributes = new JsonArray(); JsonArray inheritedFields = new JsonArray(); // The locally declared set of methods. @@ -471,6 +488,7 @@ public class JsonBuilder { break; } JsonArray methodArray = new JsonArray(); + JsonArray relationArray = new JsonArray(); JsonArray attributeArray = new JsonArray(); // Set to keep track of which method names have already been listed for // the current type. @@ -486,6 +504,10 @@ public class JsonBuilder { if (isAttribute(original)) { // Add to attributes inherited from the current superclass. attributeArray.add(original.name()); + } else if (isRelation(original)) { + // Add to relations inherited from the current superclass. + System.out.println("got inherited relation"); + relationArray.add(original.name()); } else { // Add to methods inherited from the current superclass. methodArray.add(original.name()); @@ -504,6 +526,7 @@ public class JsonBuilder { } } } + // FIXME: array conversion should be put in extra method if (!methodArray.isEmpty()) { JsonObject inherited = new JsonObject(); inherited.add("superclass", typeRef(superclass)); @@ -514,6 +537,16 @@ public class JsonBuilder { inherited.add("members", sorted); inheritedMethods.add(inherited); } + if (!relationArray.isEmpty()) { + JsonObject inherited = new JsonObject(); + inherited.add("superclass", typeRef(superclass)); + JsonArray sorted = new JsonArray(); + for (JsonValue member : Sorting.sortBy(relationArray, Sorting.jsonStringFun)) { + sorted.add(member); + } + inherited.add("members", sorted); + inheritedRelations.add(inherited); + } if (!attributeArray.isEmpty()) { JsonObject inherited = new JsonObject(); inherited.add("superclass", typeRef(superclass)); @@ -542,6 +575,9 @@ public class JsonBuilder { if (!inheritedAttributes.isEmpty()) { obj.add("inherited_attributes", inheritedAttributes); } + if (!inheritedRelations.isEmpty()) { + obj.add("inherited_relations", inheritedRelations); + } if (!inheritedFields.isEmpty()) { obj.add("inherited_fields", inheritedFields); } @@ -557,6 +593,15 @@ public class JsonBuilder { return !(doc == null || doc.get("attribute").stringValue("").isEmpty()); } + /** + * @return {@code true} if the argument is a relation, + * {@code false} if it is an ordinary method. + */ + private static boolean isRelation(MethodDecl method) { + JsonObject doc = method.jsonDocObject(); + return !(doc == null || doc.get("relation").stringValue("").isEmpty()); + } + private static JsonArray groupify(Map<String, JsonArray> groupMap, String[] kinds) { JsonArray groups = new JsonArray(); for (String kind : kinds) {