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/01/15 11:37:24 UTC
groovy git commit: Minor refactoring: extract GroovydocManager from
AstBuilder
Repository: groovy
Updated Branches:
refs/heads/parrot a9d95e04e -> a7b90046d
Minor refactoring: extract GroovydocManager from AstBuilder
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/a7b90046
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/a7b90046
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/a7b90046
Branch: refs/heads/parrot
Commit: a7b90046dacba1db53e49359fcda07b785ea9829
Parents: a9d95e0
Author: sunlan <su...@apache.org>
Authored: Sun Jan 15 19:37:10 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Sun Jan 15 19:37:10 2017 +0800
----------------------------------------------------------------------
.../apache/groovy/parser/antlr4/AstBuilder.java | 125 ++---------------
.../groovy/parser/antlr4/GroovydocManager.java | 133 +++++++++++++++++++
.../parser/antlr4/GroovyParserTest.groovy | 56 ++++----
3 files changed, 169 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/a7b90046/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 9645000..539b6f2 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
@@ -22,7 +22,6 @@ import groovy.lang.IntRange;
import org.antlr.v4.runtime.ANTLRErrorListener;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.Token;
@@ -167,6 +166,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
this.parser.setErrorHandler(new DescriptiveErrorStrategy());
this.tryWithResourcesASTTransformation = new TryWithResourcesASTTransformation(this);
+ this.groovydocManager = new GroovydocManager(this);
}
private GroovyParserRuleContext buildCST() {
@@ -955,7 +955,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
classNodeList.add(classNode);
}
- this.attachDocCommentAsMetaData(classNode, ctx);
+ groovydocManager.attachDocCommentAsMetaData(classNode, ctx);
return classNode;
}
@@ -1030,7 +1030,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(enumConstant::addAnnotation);
- this.attachDocCommentAsMetaData(enumConstant, ctx);
+ groovydocManager.attachDocCommentAsMetaData(enumConstant, ctx);
return this.configureAST(enumConstant, ctx);
}
@@ -1314,7 +1314,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
}
}
- this.attachDocCommentAsMetaData(methodNode, ctx);
+ groovydocManager.attachDocCommentAsMetaData(methodNode, ctx);
return methodNode;
}
@@ -1438,7 +1438,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
initialValue);
modifierManager.attachAnnotations(fieldNode);
- this.attachDocCommentAsMetaData(fieldNode, ctx);
+ groovydocManager.attachDocCommentAsMetaData(fieldNode, ctx);
this.configureAST(fieldNode, ctx);
} else {
@@ -1456,8 +1456,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
fieldNode.setSynthetic(!classNode.isInterface());
modifierManager.attachAnnotations(fieldNode);
- this.attachDocCommentAsMetaData(fieldNode, ctx);
- this.attachDocCommentAsMetaData(propertyNode, ctx);
+ groovydocManager.attachDocCommentAsMetaData(fieldNode, ctx);
+ groovydocManager.attachDocCommentAsMetaData(propertyNode, ctx);
this.configureAST(fieldNode, ctx);
this.configureAST(propertyNode, ctx);
@@ -4402,118 +4402,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
}
}
- /**
- * Attach doc comment to member node as meta data
- * <p>
- */
- private void attachDocCommentAsMetaData(ASTNode node, GroovyParserRuleContext ctx) {
- if (!EXTRACTING_DOC_COMMENT_ENABLED) {
- return;
- }
-
- if (!asBoolean(node) || !asBoolean(ctx)) {
- return;
- }
-
- String docCommentNodeText = this.findDocCommentByNode(ctx);
-
- if (!asBoolean((Object) docCommentNodeText)) {
- return;
- }
-
- node.putNodeMetaData(DOC_COMMENT, docCommentNodeText);
- }
-
- private String findDocCommentByNode(ParserRuleContext node) {
- if (!asBoolean(node)) {
- return null;
- }
-
- if (node instanceof ClassBodyContext) {
- return null;
- }
-
- ParserRuleContext parentContext = node.getParent();
-
- if (!asBoolean(parentContext)) {
- return null;
- }
-
- String docCommentNodeText = null;
- boolean sameTypeNodeBefore = false;
- for (ParseTree child : parentContext.children) {
-
- if (node == child) {
- // if no doc comment node found and no siblings of same type before the node,
- // try to find doc comment node of its parent
- if (!asBoolean((Object) docCommentNodeText) && !sameTypeNodeBefore) {
- return findDocCommentByNode(parentContext);
- }
-
- return docCommentNodeText;
- }
-
- if (node.getClass() == child.getClass()) { // e.g. ClassBodyDeclarationContext == ClassBodyDeclarationContext
- docCommentNodeText = null;
- sameTypeNodeBefore = true;
- continue;
- }
-
- if (!(child instanceof NlsContext || child instanceof SepContext)) {
- continue;
- }
-
- // doc comments are treated as NL
- List<? extends TerminalNode> nlList =
- child instanceof NlsContext
- ? ((NlsContext) child).NL()
- : ((SepContext) child).NL();
-
- int nlListSize = nlList.size();
- if (0 == nlListSize) {
- continue;
- }
-
- for (int i = nlListSize - 1; i >= 0; i--) {
- String text = nlList.get(i).getText();
-
- if (text.matches("\\s+")) {
- continue;
- }
-
- if (text.startsWith(DOC_COMMENT_PREFIX)) {
- docCommentNodeText = text;
- } else {
- docCommentNodeText = null;
- }
-
- break;
- }
- }
-
- throw new GroovyBugError("node can not be found: " + node.getText()); // The exception should never be thrown!
- }
-
- private static final String EXTRACT_DOC_COMMENT = "groovy.extract.doc.comment";
- private static final boolean EXTRACTING_DOC_COMMENT_ENABLED;
-
- static {
- boolean edce;
- try {
- edce = "true".equals(System.getProperty(EXTRACT_DOC_COMMENT));
- } catch (Exception e) {
- edce = false;
- }
-
- EXTRACTING_DOC_COMMENT_ENABLED = edce;
- }
-
private final ModuleNode moduleNode;
private final SourceUnit sourceUnit;
private final ClassLoader classLoader; // Our ClassLoader, which provides information on external types
private final GroovyLangLexer lexer;
private final GroovyLangParser parser;
private final TryWithResourcesASTTransformation tryWithResourcesASTTransformation;
+ private final GroovydocManager groovydocManager;
private final List<ClassNode> classNodeList = new LinkedList<>();
private final Deque<ClassNode> classNodeStack = new ArrayDeque<>();
private final Deque<List<InnerClassNode>> anonymousInnerClassesDefinedInMethodStack = new ArrayDeque<>();
@@ -4536,10 +4431,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
private static final Set<String> PRIMITIVE_TYPE_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("boolean", "char", "byte", "short", "int", "long", "float", "double")));
private static final Logger LOGGER = Logger.getLogger(AstBuilder.class.getName());
- private static final String DOC_COMMENT_PREFIX = "/**";
-
- // keys for meta data
- public static final String DOC_COMMENT = "_DOC_COMMENT";
private static final String IS_INSIDE_PARENTHESES = "_IS_INSIDE_PARENTHESES";
private static final String IS_INSIDE_INSTANCEOF_EXPR = "_IS_INSIDE_INSTANCEOF_EXPR";
private static final String IS_SWITCH_DEFAULT = "_IS_SWITCH_DEFAULT";
http://git-wip-us.apache.org/repos/asf/groovy/blob/a7b90046/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
new file mode 100644
index 0000000..c0332d6
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovydocManager.java
@@ -0,0 +1,133 @@
+package org.apache.groovy.parser.antlr4;
+
+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 java.util.List;
+
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
+
+/**
+ * A utilities for managing groovydoc, e.g.
+ * 1) extracting groovydoc from groovy AST;
+ * 2) TODO extracting tags from groovydoc;
+ * 3) attach groovydoc to AST node as metadata
+ */
+public class GroovydocManager {
+ public static final String DOC_COMMENT = "_DOC_COMMENT"; // keys for meta data
+ private static final String DOC_COMMENT_PREFIX = "/**";
+ 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;
+ private AstBuilder astBuilder;
+
+ static {
+ boolean edce;
+ try {
+ edce = TRUE_STR.equals(System.getProperty(EXTRACT_DOC_COMMENT));
+ } catch (Exception e) {
+ edce = false;
+ }
+
+ EXTRACTING_DOC_COMMENT_ENABLED = edce;
+ }
+
+ public GroovydocManager(AstBuilder astBuilder) {
+ this.astBuilder = astBuilder;
+ }
+
+ /**
+ * Attach doc comment to member node as meta data
+ * <p>
+ */
+ public void attachDocCommentAsMetaData(ASTNode node, GroovyParser.GroovyParserRuleContext ctx) {
+ if (!EXTRACTING_DOC_COMMENT_ENABLED) {
+ return;
+ }
+
+ if (!asBoolean(node) || !asBoolean(ctx)) {
+ return;
+ }
+
+ String docCommentNodeText = this.findDocCommentByNode(ctx);
+
+ if (!asBoolean((Object) docCommentNodeText)) {
+ return;
+ }
+
+ node.putNodeMetaData(DOC_COMMENT, docCommentNodeText);
+ }
+
+ private String findDocCommentByNode(ParserRuleContext node) {
+ if (!asBoolean(node)) {
+ return null;
+ }
+
+ if (node instanceof GroovyParser.ClassBodyContext) {
+ return null;
+ }
+
+ ParserRuleContext parentContext = node.getParent();
+
+ if (!asBoolean(parentContext)) {
+ return null;
+ }
+
+ String docCommentNodeText = null;
+ boolean sameTypeNodeBefore = false;
+ for (ParseTree child : parentContext.children) {
+
+ if (node == child) {
+ // if no doc comment node found and no siblings of same type before the node,
+ // try to find doc comment node of its parent
+ if (!asBoolean((Object) docCommentNodeText) && !sameTypeNodeBefore) {
+ return findDocCommentByNode(parentContext);
+ }
+
+ return docCommentNodeText;
+ }
+
+ if (node.getClass() == child.getClass()) { // e.g. ClassBodyDeclarationContext == ClassBodyDeclarationContext
+ docCommentNodeText = null;
+ sameTypeNodeBefore = true;
+ continue;
+ }
+
+ if (!(child instanceof GroovyParser.NlsContext || child instanceof GroovyParser.SepContext)) {
+ continue;
+ }
+
+ // doc comments are treated as NL
+ List<? extends TerminalNode> nlList =
+ child instanceof GroovyParser.NlsContext
+ ? ((GroovyParser.NlsContext) child).NL()
+ : ((GroovyParser.SepContext) child).NL();
+
+ int nlListSize = nlList.size();
+ if (0 == nlListSize) {
+ continue;
+ }
+
+ for (int i = nlListSize - 1; i >= 0; i--) {
+ String text = nlList.get(i).getText();
+
+ if (text.matches("\\s+")) {
+ continue;
+ }
+
+ if (text.startsWith(DOC_COMMENT_PREFIX)) {
+ docCommentNodeText = text;
+ } else {
+ docCommentNodeText = null;
+ }
+
+ break;
+ }
+ }
+
+ throw new GroovyBugError("node can not be found: " + node.getText()); // The exception should never be thrown!
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/a7b90046/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 e0f833a..4344f30 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
@@ -52,34 +52,34 @@ class GroovyParserTest extends GroovyTestCase {
List<ClassNode> classes = new ArrayList<>(newAST.classes).sort { c1, c2 -> c1.name <=> c2.name };
List<MethodNode> methods = new ArrayList<>(newAST.methods).sort { m1, m2 -> m1.name <=> m2.name };
- assert classes[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class Comments */'
- assert classes[0].fields[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.SOME_VAR */'
- assert classes[0].fields[1].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.SOME_VAR2 */'
- assert classes[0].fields[2].nodeMetaData[AstBuilder.DOC_COMMENT] == null
- assert classes[0].fields[3].nodeMetaData[AstBuilder.DOC_COMMENT] == null
- assert classes[0].declaredConstructors[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.constructor1 */'
- assert classes[0].methods[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m1 */'
- assert classes[0].methods[1].nodeMetaData[AstBuilder.DOC_COMMENT] == null
- assert classes[0].methods[2].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m3 */'
-
- assert classes[1].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class InnerClazz */'
- assert classes[1].fields[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test InnerClazz.SOME_VAR3 */'
- assert classes[1].fields[1].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test InnerClazz.SOME_VAR4 */'
- assert classes[1].methods[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m4 */'
- assert classes[1].methods[1].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m5 */'
-
- assert classes[2].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class InnerEnum */'
- assert classes[2].fields[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * InnerEnum.NEW */'
- assert classes[2].fields[1].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * InnerEnum.OLD */'
-
- assert classes[3].nodeMetaData[AstBuilder.DOC_COMMENT] == null
-
- assert classes[4].fields[0].nodeMetaData[AstBuilder.DOC_COMMENT] == null
-
- assert classes[5].nodeMetaData[AstBuilder.DOC_COMMENT] == null
-
- assert methods[0].nodeMetaData[AstBuilder.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test someScriptMethod1 */'
- assert methods[1].nodeMetaData[AstBuilder.DOC_COMMENT] == null
+ assert classes[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class Comments */'
+ assert classes[0].fields[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.SOME_VAR */'
+ assert classes[0].fields[1].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.SOME_VAR2 */'
+ assert classes[0].fields[2].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+ assert classes[0].fields[3].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+ assert classes[0].declaredConstructors[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.constructor1 */'
+ assert classes[0].methods[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m1 */'
+ assert classes[0].methods[1].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+ assert classes[0].methods[2].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m3 */'
+
+ assert classes[1].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class InnerClazz */'
+ assert classes[1].fields[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test InnerClazz.SOME_VAR3 */'
+ assert classes[1].fields[1].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test InnerClazz.SOME_VAR4 */'
+ assert classes[1].methods[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m4 */'
+ assert classes[1].methods[1].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test Comments.m5 */'
+
+ assert classes[2].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test class InnerEnum */'
+ assert classes[2].fields[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * InnerEnum.NEW */'
+ assert classes[2].fields[1].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * InnerEnum.OLD */'
+
+ assert classes[3].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+
+ assert classes[4].fields[0].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+
+ assert classes[5].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
+
+ assert methods[0].nodeMetaData[GroovydocManager.DOC_COMMENT].replaceAll(/\r?\n/, '') == '/** * test someScriptMethod1 */'
+ assert methods[1].nodeMetaData[GroovydocManager.DOC_COMMENT] == null
}
void "test groovy core - PackageDeclaration"() {