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 2017/04/09 17:16:46 UTC

groovy git commit: Store groovydoc at runtime on demand

Repository: groovy
Updated Branches:
  refs/heads/parrot 921fa3d90 -> 0169177ce


Store groovydoc at runtime on demand


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/0169177c
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/0169177c
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/0169177c

Branch: refs/heads/parrot
Commit: 0169177ceb3ecd54a27820e814990b76b6584062
Parents: 921fa3d
Author: sunlan <su...@apache.org>
Authored: Mon Apr 10 01:16:36 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Mon Apr 10 01:16:36 2017 +0800

----------------------------------------------------------------------
 src/main/groovy/lang/Groovydoc.java             | 17 +++++++
 .../apache/groovy/parser/antlr4/AstBuilder.java | 12 ++---
 .../groovy/parser/antlr4/GroovydocManager.java  | 47 ++++++++++++++++--
 .../parser/antlr4/GroovyParserTest.groovy       |  4 ++
 .../test/resources/core/Groovydoc_01x.groovy    | 52 ++++++++++++++++++++
 5 files changed, 122 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/0169177c/src/main/groovy/lang/Groovydoc.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/Groovydoc.java b/src/main/groovy/lang/Groovydoc.java
new file mode 100644
index 0000000..d27dfcb
--- /dev/null
+++ b/src/main/groovy/lang/Groovydoc.java
@@ -0,0 +1,17 @@
+package groovy.lang;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Store the groovydoc for the annotated elements
+ *
+ * Created by Daniel on 2017/4/9.
+ */
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Groovydoc {
+    String value();
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0169177c/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index e59dd5f..9f4eca3 100644
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -951,7 +951,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             classNodeList.add(classNode);
         }
 
-        groovydocManager.attachDocCommentAsMetaData(classNode, ctx);
+        groovydocManager.handle(classNode, ctx);
 
         return classNode;
     }
@@ -1026,7 +1026,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
         this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(enumConstant::addAnnotation);
 
-        groovydocManager.attachDocCommentAsMetaData(enumConstant, ctx);
+        groovydocManager.handle(enumConstant, ctx);
 
         return this.configureAST(enumConstant, ctx);
     }
@@ -1256,7 +1256,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
         validateMethodDeclaration(ctx, methodNode);
 
-        groovydocManager.attachDocCommentAsMetaData(methodNode, ctx);
+        groovydocManager.handle(methodNode, ctx);
 
         return methodNode;
     }
@@ -1495,7 +1495,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                                 initialValue);
                 modifierManager.attachAnnotations(fieldNode);
 
-                groovydocManager.attachDocCommentAsMetaData(fieldNode, ctx);
+                groovydocManager.handle(fieldNode, ctx);
 
                 this.configureAST(fieldNode, ctx);
             } else {
@@ -1513,8 +1513,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                 fieldNode.setSynthetic(!classNode.isInterface());
                 modifierManager.attachAnnotations(fieldNode);
 
-                groovydocManager.attachDocCommentAsMetaData(fieldNode, ctx);
-                groovydocManager.attachDocCommentAsMetaData(propertyNode, ctx);
+                groovydocManager.handle(fieldNode, ctx);
+                groovydocManager.handle(propertyNode, ctx);
 
                 this.configureAST(fieldNode, ctx);
                 this.configureAST(propertyNode, ctx);

http://git-wip-us.apache.org/repos/asf/groovy/blob/0169177c/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java
index c0332d6..12d08c9 100644
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java
@@ -1,10 +1,15 @@
 package org.apache.groovy.parser.antlr4;
 
+import groovy.lang.Groovydoc;
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
 
 import java.util.List;
 
@@ -22,6 +27,8 @@ public class GroovydocManager {
     private static final String EXTRACT_DOC_COMMENT = "groovy.extract.doc.comment";
     private static final String TRUE_STR = "true";
     private static final boolean EXTRACTING_DOC_COMMENT_ENABLED;
+    public static final String VALUE = "value";
+    public static final String GROOVYDOC_PATTERN = "(?s)\\s*/[*][*]\\s+(\\s+[*]\\s*)*@Groovydoc.+?[*]/\\s*";
     private AstBuilder astBuilder;
 
     static {
@@ -41,14 +48,22 @@ public class GroovydocManager {
 
     /**
      * Attach doc comment to member node as meta data
-     * <p>
+     *
      */
-    public void attachDocCommentAsMetaData(ASTNode node, GroovyParser.GroovyParserRuleContext ctx) {
-        if (!EXTRACTING_DOC_COMMENT_ENABLED) {
+    public void handle(ASTNode node, GroovyParser.GroovyParserRuleContext ctx) {
+        if (!asBoolean(node) || !asBoolean(ctx)) {
             return;
         }
 
-        if (!asBoolean(node) || !asBoolean(ctx)) {
+        attachDocCommentAsMetaData(node, ctx);
+        attachGroovydocAnnotation(node, ctx);
+    }
+
+    /*
+     * Attach doc comment to member node as meta data
+     */
+    private void attachDocCommentAsMetaData(ASTNode node, GroovyParser.GroovyParserRuleContext ctx) {
+        if (!EXTRACTING_DOC_COMMENT_ENABLED) {
             return;
         }
 
@@ -61,6 +76,30 @@ public class GroovydocManager {
         node.putNodeMetaData(DOC_COMMENT, docCommentNodeText);
     }
 
+    private void attachGroovydocAnnotation(ASTNode node, GroovyParser.GroovyParserRuleContext ctx) {
+        if (!(node instanceof AnnotatedNode)) {
+            return;
+        }
+
+        String docCommentNodeText;
+
+        if (EXTRACTING_DOC_COMMENT_ENABLED) { // try to reuse the result of extracting doc comment for better performance
+            docCommentNodeText = node.getNodeMetaData(DOC_COMMENT);
+        } else {
+            docCommentNodeText = this.findDocCommentByNode(ctx);
+        }
+
+        if (null == docCommentNodeText || !docCommentNodeText.matches(GROOVYDOC_PATTERN)) {
+            return;
+        }
+
+        AnnotatedNode annotatedNode = (AnnotatedNode) node;
+        AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make(Groovydoc.class));
+        annotationNode.addMember(VALUE, new ConstantExpression(docCommentNodeText));
+        annotatedNode.addAnnotation(annotationNode);
+    }
+
+
     private String findDocCommentByNode(ParserRuleContext node) {
         if (!asBoolean(node)) {
             return null;

http://git-wip-us.apache.org/repos/asf/groovy/blob/0169177c/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 14b67f2..0750c37 100644
--- a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -342,6 +342,10 @@ class GroovyParserTest extends GroovyTestCase {
         doRunAndTest('core/Array_01x.groovy');
     }
 
+    void "test groovy core - Groovydoc"() {
+        doRunAndTest('core/Groovydoc_01x.groovy');
+    }
+
     void "test groovy core - BUG"() {
         doRunAndTest('bugs/BUG-GROOVY-4757.groovy');
         doRunAndTest('bugs/GROOVY-3898.groovy');

http://git-wip-us.apache.org/repos/asf/groovy/blob/0169177c/subprojects/groovy-parser-antlr4/src/test/resources/core/Groovydoc_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/Groovydoc_01x.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/Groovydoc_01x.groovy
new file mode 100644
index 0000000..c4c14c8
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/Groovydoc_01x.groovy
@@ -0,0 +1,52 @@
+/**
+ * @Groovydoc
+ * class AA
+ */
+class AA {
+    /**
+     * @Groovydoc
+     * field SOME_FIELD
+     */
+    public static final int SOME_FIELD = 1;
+
+    /**
+     * @Groovydoc
+     * constructor AA
+     */
+    public AA() {
+
+    }
+
+    /**
+     * @Groovydoc
+     * method m
+     */
+    public void m() {
+
+    }
+
+    /**
+     * @Groovydoc
+     * class InnerClass
+     */
+    class InnerClass {
+
+    }
+
+
+}
+
+/**
+ * @Groovydoc
+ * annotation BB
+ */
+@interface BB {
+
+}
+
+assert AA.class.getAnnotation(groovy.lang.Groovydoc).value().contains('class AA')
+assert AA.class.getMethod('m', new Class[0]).getAnnotation(groovy.lang.Groovydoc).value().contains('method m')
+assert AA.class.getConstructor().getAnnotation(groovy.lang.Groovydoc).value().contains('constructor AA')
+assert AA.class.getField('SOME_FIELD').getAnnotation(groovy.lang.Groovydoc).value().contains('field SOME_FIELD')
+assert AA.class.getDeclaredClasses().find {it.simpleName.contains('InnerClass')}.getAnnotation(groovy.lang.Groovydoc).value().contains('class InnerClass')
+assert BB.class.getAnnotation(groovy.lang.Groovydoc).value().contains('annotation BB')
\ No newline at end of file