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