You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/09/26 08:45:27 UTC
[groovy] 01/05: Minor refactoring: implement `makeType` for antlr4
parser plugin
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit e59b5529e34291443f4965dcd78b6eb0a9f37e1b
Author: Daniel.Sun <re...@hotmail.com>
AuthorDate: Wed Sep 25 14:36:08 2019 +0800
Minor refactoring: implement `makeType` for antlr4 parser plugin
As antlr2 parser will be removed in the future, we should not rely on its API
---
.../codehaus/groovy/ast/tools/GenericsUtils.java | 33 ++++-------
.../MarkupTemplateTypeCheckingExtension.groovy | 41 +++++--------
.../groovy/parser/antlr4/Antlr4ParserPlugin.java | 68 ++++++++++++++++++++++
3 files changed, 91 insertions(+), 51 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 082d4b1..69beb13 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -18,14 +18,11 @@
*/
package org.codehaus.groovy.ast.tools;
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
import groovy.lang.Tuple2;
import groovy.transform.stc.IncorrectTypeHintException;
+import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin;
+import org.apache.groovy.parser.antlr4.Antlr4PluginFactory;
import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.antlr.AntlrParserPlugin;
-import org.codehaus.groovy.antlr.parser.GroovyLexer;
-import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
@@ -34,15 +31,14 @@ import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.stmt.EmptyStatement;
+import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.ParserPluginFactory;
import org.codehaus.groovy.control.ResolveVisitor;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.runtime.memoize.ConcurrentSoftCache;
import org.codehaus.groovy.runtime.memoize.EvictableCache;
-import org.codehaus.groovy.syntax.ParserException;
-import org.codehaus.groovy.syntax.Reduction;
-import java.io.StringReader;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,7 +49,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import static groovy.lang.Tuple.tuple;
@@ -587,20 +582,12 @@ public class GenericsUtils {
final CompilationUnit compilationUnit,
final MethodNode mn,
final ASTNode usage) {
- GroovyLexer lexer = new GroovyLexer(new StringReader("DummyNode<" + option + ">"));
- final GroovyRecognizer rn = GroovyRecognizer.make(lexer);
+
try {
- rn.classOrInterfaceType(true);
- final AtomicReference<ClassNode> ref = new AtomicReference<ClassNode>();
- AntlrParserPlugin plugin = new AntlrParserPlugin() {
- @Override
- public ModuleNode buildAST(final SourceUnit sourceUnit, final ClassLoader classLoader, final Reduction cst) throws ParserException {
- ref.set(makeTypeWithArguments(rn.getAST()));
- return null;
- }
- };
- plugin.buildAST(null, null, null);
- ClassNode parsedNode = ref.get();
+ Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(compilationUnit.getConfiguration());
+ Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin();
+ ClassNode parsedNode = antlr4ParserPlugin.makeType("DummyNode<" + option + ">");
+
// the returned node is DummyNode<Param1, Param2, Param3, ...)
GenericsType[] parsedNodeGenericsTypes = parsedNode.getGenericsTypes();
if (parsedNodeGenericsTypes == null) {
@@ -612,7 +599,7 @@ public class GenericsUtils {
signature[i] = resolveClassNode(sourceUnit, compilationUnit, mn, usage, genericsType.getType());
}
return signature;
- } catch (RecognitionException | ParserException | TokenStreamException e) {
+ } catch (CompilationFailedException e) {
sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
}
return null;
diff --git a/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy b/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
index 9d91fcf..7db4dc7 100644
--- a/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
+++ b/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
@@ -19,9 +19,8 @@
package groovy.text.markup
import groovy.transform.CompileStatic
-import org.codehaus.groovy.antlr.AntlrParserPlugin
-import org.codehaus.groovy.antlr.parser.GroovyLexer
-import org.codehaus.groovy.antlr.parser.GroovyRecognizer
+import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin
+import org.apache.groovy.parser.antlr4.Antlr4PluginFactory
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ClassCodeExpressionTransformer
import org.codehaus.groovy.ast.ClassHelper
@@ -39,18 +38,16 @@ import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.TupleExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.stmt.EmptyStatement
+import org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.control.ParserPluginFactory
import org.codehaus.groovy.control.ResolveVisitor
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.messages.SyntaxErrorMessage
-import org.codehaus.groovy.syntax.ParserException
-import org.codehaus.groovy.syntax.Reduction
import org.codehaus.groovy.syntax.SyntaxException
import org.codehaus.groovy.syntax.Types
import org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport
import org.codehaus.groovy.transform.stc.TypeCheckingContext
-import java.util.concurrent.atomic.AtomicReference
-
import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isAssignment
@@ -178,23 +175,11 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
@CompileStatic
private static ClassNode buildNodeFromString(String option, TypeCheckingContext ctx) {
- GroovyLexer lexer = new GroovyLexer(new StringReader(option))
- final GroovyRecognizer rn = GroovyRecognizer.make(lexer)
- rn.classOrInterfaceType(true);
- final AtomicReference<ClassNode> ref = new AtomicReference<ClassNode>();
- AntlrParserPlugin plugin = new AntlrParserPlugin() {
- @Override
- public ModuleNode buildAST(
- final SourceUnit sourceUnit,
- final ClassLoader classLoader, final Reduction cst) throws ParserException {
- ref.set(makeTypeWithArguments(rn.getAST()));
- return null;
- }
- };
- plugin.buildAST(null, null, null);
- ClassNode parsedNode = ref.get();
- ClassNode dummyClass = new ClassNode("dummy", 0, ClassHelper.OBJECT_TYPE);
- dummyClass.setModule(new ModuleNode(ctx.source));
+ Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(CompilerConfiguration.DEFAULT)
+ Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin()
+ ClassNode parsedNode = antlr4ParserPlugin.makeType(option)
+ ClassNode dummyClass = new ClassNode("dummy", 0, ClassHelper.OBJECT_TYPE)
+ dummyClass.setModule(new ModuleNode(ctx.source))
MethodNode dummyMN = new MethodNode(
"dummy",
0,
@@ -203,16 +188,16 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
ClassNode.EMPTY_ARRAY,
EmptyStatement.INSTANCE
)
- dummyClass.addMethod(dummyMN);
+ dummyClass.addMethod(dummyMN)
ResolveVisitor visitor = new ResolveVisitor(ctx.compilationUnit) {
@Override
- public void addError(final String msg, final ASTNode expr) {
+ void addError(final String msg, final ASTNode expr) {
ctx.errorCollector.addErrorAndContinue(new SyntaxErrorMessage(
new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()),
ctx.source)
- );
+ )
}
- };
+ }
visitor.startResolving(dummyClass, ctx.source)
return dummyMN.getReturnType()
}
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/Antlr4ParserPlugin.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/Antlr4ParserPlugin.java
index fa6b381..44e76e5 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/Antlr4ParserPlugin.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/Antlr4ParserPlugin.java
@@ -18,10 +18,18 @@
*/
package org.apache.groovy.parser.antlr4;
+import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ModuleNode;
+import org.codehaus.groovy.ast.expr.DeclarationExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.ErrorCollector;
import org.codehaus.groovy.control.ParserPlugin;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
@@ -32,6 +40,9 @@ import org.codehaus.groovy.syntax.Reduction;
import java.io.IOException;
import java.io.Reader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
/**
* A parser plugin for the new parser
@@ -77,4 +88,61 @@ public class Antlr4ParserPlugin implements ParserPlugin {
return builder.buildAST();
}
+
+ /**
+ * Create ClassNode instance for type string
+ *
+ * @param typeStr type string, e.g. List
+ * @return a {@link ClassNode} instance
+ * @since 3.0.0
+ */
+ public ClassNode makeType(String typeStr) {
+ SourceUnit sourceUnit =
+ new SourceUnit(
+ "Script" + System.nanoTime(),
+ typeStr + " v",
+ compilerConfiguration,
+ AccessController.doPrivileged(
+ new PrivilegedAction<GroovyClassLoader>() {
+ @Override
+ public GroovyClassLoader run() {
+ return new GroovyClassLoader();
+ }
+ }),
+ new ErrorCollector(compilerConfiguration)
+ );
+ AstBuilder builder = new AstBuilder(sourceUnit, compilerConfiguration);
+ ModuleNode moduleNode = builder.buildAST();
+
+ List<Statement> statementList = moduleNode.getStatementBlock().getStatements();
+
+ Statement statement;
+ try {
+ statement = statementList.get(0);
+ } catch (IndexOutOfBoundsException e) {
+ throw new GroovyBugError(statementList + " is empty");
+ }
+
+ if (!(statement instanceof ExpressionStatement)) {
+ throw new GroovyBugError(statement + " is not an instance of ExpressionStatement");
+ }
+
+ ExpressionStatement expressionStatement = (ExpressionStatement) statement;
+ Expression expression = expressionStatement.getExpression();
+
+ if (!(expression instanceof DeclarationExpression)) {
+ throw new GroovyBugError(expression + " is not an instance of DeclarationExpression");
+ }
+
+ DeclarationExpression declarationExpression = (DeclarationExpression) expression;
+ Expression leftExpression = declarationExpression.getLeftExpression();
+
+ if (!(leftExpression instanceof VariableExpression)) {
+ throw new GroovyBugError(leftExpression + " is not an instance of VariableExpression");
+ }
+
+ VariableExpression variableExpression = (VariableExpression) leftExpression;
+
+ return variableExpression.getType();
+ }
}