You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/12/22 17:19:07 UTC
[groovy] 02/02: Extract javadoc via traversing AST
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch refine-groovydoc
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit f2a4fc88145d76026281c3ff69e1e46c8d5bbc47
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sun Dec 23 01:18:15 2018 +0800
Extract javadoc via traversing AST
---
.../tools/groovydoc/SimpleGroovyClassDoc.java | 390 ---------------------
.../groovydoc/SimpleJavaClassDocAssembler.java | 125 ++++---
.../SimpleJavaClassDocAssemblerTest.groovy | 3 +-
.../SimpleJavaClassDocAssemblerTest1.java | 45 +++
4 files changed, 108 insertions(+), 455 deletions(-)
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleGroovyClassDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
deleted file mode 100644
index 85c5cf6..0000000
--- a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.groovy.tools.groovydoc;
-
-import org.codehaus.groovy.groovydoc.GroovyAnnotationRef;
-import org.codehaus.groovy.groovydoc.GroovyClassDoc;
-import org.codehaus.groovy.groovydoc.GroovyConstructorDoc;
-import org.codehaus.groovy.groovydoc.GroovyFieldDoc;
-import org.codehaus.groovy.groovydoc.GroovyMethodDoc;
-import org.codehaus.groovy.groovydoc.GroovyPackageDoc;
-import org.codehaus.groovy.groovydoc.GroovyType;
-
-public class SimpleGroovyClassDoc implements GroovyClassDoc {
- @Override
- public GroovyConstructorDoc[] constructors() {
- return new GroovyConstructorDoc[0];
- }
-
- @Override
- public GroovyConstructorDoc[] constructors(boolean filter) {
- return new GroovyConstructorDoc[0];
- }
-
- @Override
- public boolean definesSerializableFields() {
- return false;
- }
-
- @Override
- public GroovyFieldDoc[] enumConstants() {
- return new GroovyFieldDoc[0];
- }
-
- @Override
- public GroovyFieldDoc[] fields() {
- return new GroovyFieldDoc[0];
- }
-
- @Override
- public GroovyFieldDoc[] properties() {
- return new GroovyFieldDoc[0];
- }
-
- @Override
- public GroovyFieldDoc[] fields(boolean filter) {
- return new GroovyFieldDoc[0];
- }
-
- @Override
- public GroovyClassDoc findClass(String className) {
- return null;
- }
-
- @Override
- public GroovyClassDoc[] importedClasses() {
- return new GroovyClassDoc[0];
- }
-
- @Override
- public GroovyPackageDoc[] importedPackages() {
- return new GroovyPackageDoc[0];
- }
-
- @Override
- public GroovyClassDoc[] innerClasses() {
- return new GroovyClassDoc[0];
- }
-
- @Override
- public GroovyClassDoc[] innerClasses(boolean filter) {
- return new GroovyClassDoc[0];
- }
-
- @Override
- public GroovyClassDoc[] interfaces() {
- return new GroovyClassDoc[0];
- }
-
- @Override
- public GroovyType[] interfaceTypes() {
- return new GroovyType[0];
- }
-
- @Override
- public boolean isAbstract() {
- return false;
- }
-
- @Override
- public boolean isExternalizable() {
- return false;
- }
-
- @Override
- public boolean isSerializable() {
- return false;
- }
-
- @Override
- public GroovyMethodDoc[] methods() {
- return new GroovyMethodDoc[0];
- }
-
- @Override
- public GroovyMethodDoc[] methods(boolean filter) {
- return new GroovyMethodDoc[0];
- }
-
- @Override
- public GroovyFieldDoc[] serializableFields() {
- return new GroovyFieldDoc[0];
- }
-
- @Override
- public GroovyMethodDoc[] serializationMethods() {
- return new GroovyMethodDoc[0];
- }
-
- @Override
- public boolean subclassOf(GroovyClassDoc gcd) {
- return false;
- }
-
- @Override
- public GroovyClassDoc superclass() {
- return null;
- }
-
- @Override
- public GroovyType superclassType() {
- return null;
- }
-
- @Override
- public String getFullPathName() {
- return null;
- }
-
- @Override
- public String getRelativeRootPath() {
- return null;
- }
-
- @Override
- public GroovyAnnotationRef[] annotations() {
- return new GroovyAnnotationRef[0];
- }
-
- @Override
- public GroovyClassDoc containingClass() {
- return null;
- }
-
- @Override
- public GroovyPackageDoc containingPackage() {
- return null;
- }
-
- @Override
- public boolean isFinal() {
- return false;
- }
-
- @Override
- public boolean isPackagePrivate() {
- return false;
- }
-
- @Override
- public boolean isPrivate() {
- return false;
- }
-
- @Override
- public boolean isProtected() {
- return false;
- }
-
- @Override
- public boolean isPublic() {
- return false;
- }
-
- @Override
- public boolean isStatic() {
- return false;
- }
-
- @Override
- public String modifiers() {
- return null;
- }
-
- @Override
- public int modifierSpecifier() {
- return 0;
- }
-
- @Override
- public String qualifiedName() {
- return null;
- }
-
- @Override
- public String commentText() {
- return null;
- }
-
- @Override
- public String getRawCommentText() {
- return null;
- }
-
- @Override
- public boolean isAnnotationType() {
- return false;
- }
-
- @Override
- public boolean isAnnotationTypeElement() {
- return false;
- }
-
- @Override
- public boolean isClass() {
- return false;
- }
-
- @Override
- public boolean isConstructor() {
- return false;
- }
-
- @Override
- public boolean isDeprecated() {
- return false;
- }
-
- @Override
- public boolean isEnum() {
- return false;
- }
-
- @Override
- public boolean isEnumConstant() {
- return false;
- }
-
- @Override
- public boolean isError() {
- return false;
- }
-
- @Override
- public boolean isException() {
- return false;
- }
-
- @Override
- public boolean isField() {
- return false;
- }
-
- @Override
- public boolean isIncluded() {
- return false;
- }
-
- @Override
- public boolean isInterface() {
- return false;
- }
-
- @Override
- public boolean isMethod() {
- return false;
- }
-
- @Override
- public boolean isOrdinaryClass() {
- return false;
- }
-
- @Override
- public String name() {
- return null;
- }
-
- @Override
- public void setRawCommentText(String arg0) {
-
- }
-
- @Override
- public String firstSentenceCommentText() {
- return null;
- }
-
- /**
- * Compares this object with the specified object for order. Returns a
- * negative integer, zero, or a positive integer as this object is less
- * than, equal to, or greater than the specified object.
- *
- * <p>The implementor must ensure
- * {@code sgn(x.compareTo(y)) == -sgn(y.compareTo(x))}
- * for all {@code x} and {@code y}. (This
- * implies that {@code x.compareTo(y)} must throw an exception iff
- * {@code y.compareTo(x)} throws an exception.)
- *
- * <p>The implementor must also ensure that the relation is transitive:
- * {@code (x.compareTo(y) > 0 && y.compareTo(z) > 0)} implies
- * {@code x.compareTo(z) > 0}.
- *
- * <p>Finally, the implementor must ensure that {@code x.compareTo(y)==0}
- * implies that {@code sgn(x.compareTo(z)) == sgn(y.compareTo(z))}, for
- * all {@code z}.
- *
- * <p>It is strongly recommended, but <i>not</i> strictly required that
- * {@code (x.compareTo(y)==0) == (x.equals(y))}. Generally speaking, any
- * class that implements the {@code Comparable} interface and violates
- * this condition should clearly indicate this fact. The recommended
- * language is "Note: this class has a natural ordering that is
- * inconsistent with equals."
- *
- * <p>In the foregoing description, the notation
- * {@code sgn(}<i>expression</i>{@code )} designates the mathematical
- * <i>signum</i> function, which is defined to return one of {@code -1},
- * {@code 0}, or {@code 1} according to whether the value of
- * <i>expression</i> is negative, zero, or positive, respectively.
- *
- * @param o the object to be compared.
- * @return a negative integer, zero, or a positive integer as this object
- * is less than, equal to, or greater than the specified object.
- * @throws NullPointerException if the specified object is null
- * @throws ClassCastException if the specified object's type prevents it
- * from being compared to this object.
- */
- @Override
- public int compareTo(Object o) {
- return 0;
- }
-
- @Override
- public boolean isPrimitive() {
- return false;
- }
-
- /**
- * The qualified name of this type excluding any dimension information.
- * For example, a two dimensional array of String returns "<code>java.lang.String</code>".
- */
- @Override
- public String qualifiedTypeName() {
- return null;
- }
-
- /**
- * The unqualified name of this type excluding any dimension or nesting information.
- * For example, the class <code>Outer.Inner</code> returns "<code>Inner</code>".
- */
- @Override
- public String simpleTypeName() {
- return null;
- }
-
- /**
- * The unqualified name of this type excluding any dimension information.
- * For example, a two dimensional array of String returns "<code>String</code>".
- */
- @Override
- public String typeName() {
- return null;
- }
-}
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssembler.java b/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssembler.java
index 1af0066..49579b9 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssembler.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssembler.java
@@ -19,16 +19,17 @@
package org.apache.groovy.tools.groovydoc;
import com.github.javaparser.JavaParser;
-import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.EnumConstantDeclaration;
import com.github.javaparser.ast.body.EnumDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.comments.JavadocComment;
-import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.visitor.GenericVisitorAdapter;
+import com.github.javaparser.javadoc.Javadoc;
import org.codehaus.groovy.groovydoc.GroovyClassDoc;
import org.codehaus.groovy.tools.groovydoc.LinkArgument;
@@ -37,9 +38,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
-import java.util.stream.Collectors;
-public class SimpleJavaClassDocAssembler {
+public class SimpleJavaClassDocAssembler extends GenericVisitorAdapter<Object, Object> {
private final String packagePath;
private final String javaSourceContent;
private final String className;
@@ -62,72 +62,69 @@ public class SimpleJavaClassDocAssembler {
}
}
- private Map<String, GroovyClassDoc> parse() {
- new VoidVisitorAdapter<Object>() {
- @Override
- public void visit(JavadocComment comment, Object arg) {
- super.visit(comment, arg);
-
- System.out.println(collect(comment));
-//
-// String title = String.format("%s (%s)", comment.getName(), packagePath);
-// System.out.println(title);
-// System.out.println(comment.get());
-// System.out.println("--------------------------");
-// Javadoc javadoc = comment.get().asJavadocComment().parse();
-// System.out.println(javadoc.getDescription().toText());
-// javadoc.getBlockTags().forEach(e -> System.out.println(e.getName() + ":" + e.getContent()));
-// System.out.println("===========================");
- }
- }.visit(JavaParser.parse(javaSourceContent), null);
-
+ public Map<String, GroovyClassDoc> getGroovyClassDocs() {
return classDocs;
}
- private static String collect(JavadocComment comment) {
- Optional<Node> commentedNode = comment.getCommentedNode();
+ public void assemble() {
+ this.visit(JavaParser.parse(javaSourceContent), null);
+ }
- if (!commentedNode.isPresent()) {
- return null;
- }
+ @Override
+ public Object visit(final ClassOrInterfaceDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
- Node node = commentedNode.get();
+ @Override
+ public Object visit(final MethodDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
- if (node instanceof MethodDeclaration) {
- MethodDeclaration methodDeclaration = (MethodDeclaration) node;
- return "Method " + methodDeclaration.getDeclarationAsString();
- }
- if (node instanceof ConstructorDeclaration) {
- ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) node;
- return "Constructor " + constructorDeclaration.getDeclarationAsString();
- }
- if (node instanceof FieldDeclaration) {
- FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
- List<String> varNames = fieldDeclaration.getVariables().stream().map(v -> v.getName().getId()).collect(Collectors.toList());
- return "Field " + String.join(", ", varNames);
- }
- if (node instanceof EnumConstantDeclaration) {
- EnumConstantDeclaration enumConstantDeclaration = (EnumConstantDeclaration) node;
- return "Enum Constant" + enumConstantDeclaration.getName();
- }
- if (node instanceof ClassOrInterfaceDeclaration) {
- ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) node;
-
- if (classOrInterfaceDeclaration.isInterface()) {
- return "Interface " + classOrInterfaceDeclaration.getName() + ": " + comment.parse().getDescription().toText();
- } else {
- return "Class " + classOrInterfaceDeclaration.getName() + ": " + comment.parse().getDescription().toText();
- }
- }
- if (node instanceof EnumDeclaration) {
- EnumDeclaration enumDeclaration = (EnumDeclaration) node;
- return "Enum " + enumDeclaration.getName();
- }
- if (node instanceof AnnotationDeclaration) {
- AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration) node;
- return "Annotation " + annotationDeclaration.getName();
+ @Override
+ public Object visit(final ConstructorDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ @Override
+ public Object visit(final FieldDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ @Override
+ public Object visit(final EnumDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ @Override
+ public Object visit(final EnumConstantDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ @Override
+ public Object visit(final AnnotationDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ @Override
+ public Object visit(final AnnotationMemberDeclaration n, final Object arg) {
+ processJavadoc(n);
+ return super.visit(n, arg);
+ }
+
+ private void processJavadoc(NodeWithJavadoc n) {
+ Optional<Javadoc> optionalJavadoc = n.getJavadoc();
+
+ if (!optionalJavadoc.isPresent()) {
+ return;
}
- return node.toString();
+ System.out.println(optionalJavadoc.get().getDescription().toText());
}
}
\ No newline at end of file
diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest.groovy b/subprojects/groovy-groovydoc/src/test/groovy/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest.groovy
index 677dd4b..9f96175 100644
--- a/subprojects/groovy-groovydoc/src/test/groovy/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest.groovy
+++ b/subprojects/groovy-groovydoc/src/test/groovy/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest.groovy
@@ -22,6 +22,7 @@ class SimpleJavaClassDocAssemblerTest extends GroovyTestCase {
void testClassDoc() {
def src = SimpleJavaClassDocAssemblerTest.getResourceAsStream('/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest1.java').text
def sjcda = new SimpleJavaClassDocAssembler('org/apache/groovy/tools/groovydoc', 'SimpleJavaClassDocAssemblerTest1.java', src, [], new Properties())
- sjcda.parse()
+ sjcda.assemble()
}
+
}
\ No newline at end of file
diff --git a/subprojects/groovy-groovydoc/src/test/resources/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest1.java b/subprojects/groovy-groovydoc/src/test/resources/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest1.java
index 87d4668..027991c 100644
--- a/subprojects/groovy-groovydoc/src/test/resources/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest1.java
+++ b/subprojects/groovy-groovydoc/src/test/resources/org/apache/groovy/tools/groovydoc/SimpleJavaClassDocAssemblerTest1.java
@@ -28,6 +28,37 @@ public class SimpleJavaClassDocAssemblerTest1 {
public static final String HELLO = "hello";
/**
+ * constructor of SimpleJavaClassDocAssemblerTest1
+ */
+ public SimpleJavaClassDocAssemblerTest1() {
+ }
+
+ /**
+ * This an inner class doc
+ */
+ public static class SomeInnerClass {
+ /**
+ * The greeting word of inner class
+ */
+ public static final String INNER_HELLO = "hello";
+
+ /**
+ * constructor of SomeInnerClass
+ */
+ public SomeInnerClass() {}
+
+ /**
+ * say hello from inner class
+ *
+ * @param name some name
+ * @return the greeting words
+ */
+ public String innerHello(String name) {
+ return HELLO + "," + name;
+ }
+ }
+
+ /**
* say hello
*
* @param name some name
@@ -37,3 +68,17 @@ public class SimpleJavaClassDocAssemblerTest1 {
return HELLO + "," + name;
}
}
+
+/**
+ * some class
+ */
+class SomeClass {
+
+}
+
+/**
+ * some enum
+ */
+enum SomeEnum {
+
+}