You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2019/11/20 19:26:25 UTC
[groovy] branch master updated: create parser-agnostic API for
parsing snippet
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
View the commit online:
https://github.com/apache/groovy/commit/f6f55ab632fe451aa8fe98ca87ecdd26b06d659a
The following commit(s) were added to refs/heads/master by this push:
new f6f55ab create parser-agnostic API for parsing snippet
f6f55ab is described below
commit f6f55ab632fe451aa8fe98ca87ecdd26b06d659a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Nov 20 12:51:53 2019 -0600
create parser-agnostic API for parsing snippet
---
.../org/codehaus/groovy/ast/tools/Antlr4Utils.java | 36 -------------
.../codehaus/groovy/ast/tools/GenericsUtils.java | 28 +++++-----
.../org/codehaus/groovy/control/ParserPlugin.java | 13 ++++-
.../MarkupTemplateTypeCheckingExtension.groovy | 8 +--
.../groovy/parser/antlr4/Antlr4ParserPlugin.java | 62 ----------------------
5 files changed, 29 insertions(+), 118 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java b/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java
deleted file mode 100644
index 05395ee..0000000
--- a/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java
+++ /dev/null
@@ -1,36 +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.codehaus.groovy.ast.tools;
-
-import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin;
-import org.apache.groovy.parser.antlr4.Antlr4PluginFactory;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.control.ParserPluginFactory;
-
-public class Antlr4Utils {
- private Antlr4Utils() {
- }
-
- public static ClassNode parse(String option, CompilerConfiguration configuration) {
- Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(configuration);
- Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin();
- return antlr4ParserPlugin.makeType(option);
- }
-}
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 bc22176..1b20724 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -18,7 +18,6 @@
*/
package org.codehaus.groovy.ast.tools;
-import groovy.lang.GroovyRuntimeException;
import groovy.lang.Tuple2;
import groovy.transform.stc.IncorrectTypeHintException;
import org.codehaus.groovy.GroovyBugError;
@@ -29,8 +28,11 @@ import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.stmt.EmptyStatement;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.ParserPlugin;
import org.codehaus.groovy.control.ResolveVisitor;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.runtime.memoize.ConcurrentSoftCache;
@@ -578,28 +580,24 @@ public class GenericsUtils {
}
}
- public static ClassNode[] parseClassNodesFromString(
- final String option,
- final SourceUnit sourceUnit,
- final CompilationUnit compilationUnit,
- final MethodNode mn,
- final ASTNode usage) {
-
+ public static ClassNode[] parseClassNodesFromString(final String option, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final MethodNode mn, final ASTNode usage) {
try {
- ClassNode parsedNode = Antlr4Utils.parse("DummyNode<" + option + ">", compilationUnit.getConfiguration());
+ ModuleNode moduleNode = ParserPlugin.buildAST("Dummy<" + option + "> dummy;", compilationUnit.getClassLoader(), compilationUnit.getConfiguration(), null);
+ DeclarationExpression dummyDeclaration = (DeclarationExpression) ((ExpressionStatement) moduleNode.getStatementBlock().getStatements().get(0)).getExpression();
// the returned node is DummyNode<Param1, Param2, Param3, ...)
- GenericsType[] parsedNodeGenericsTypes = parsedNode.getGenericsTypes();
- if (parsedNodeGenericsTypes == null) {
+ ClassNode dummyNode = dummyDeclaration.getLeftExpression().getType();
+ GenericsType[] dummyNodeGenericsTypes = dummyNode.getGenericsTypes();
+ if (dummyNodeGenericsTypes == null) {
return null;
}
- ClassNode[] signature = new ClassNode[parsedNodeGenericsTypes.length];
- for (int i = 0; i < parsedNodeGenericsTypes.length; i++) {
- final GenericsType genericsType = parsedNodeGenericsTypes[i];
+ ClassNode[] signature = new ClassNode[dummyNodeGenericsTypes.length];
+ for (int i = 0, n = dummyNodeGenericsTypes.length; i < n; i += 1) {
+ final GenericsType genericsType = dummyNodeGenericsTypes[i];
signature[i] = resolveClassNode(sourceUnit, compilationUnit, mn, usage, genericsType.getType());
}
return signature;
- } catch (GroovyRuntimeException e) {
+ } catch (Exception | LinkageError e) {
sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(), usage.getColumnNumber()));
}
return null;
diff --git a/src/main/java/org/codehaus/groovy/control/ParserPlugin.java b/src/main/java/org/codehaus/groovy/control/ParserPlugin.java
index 9b298d8..1d4f488 100644
--- a/src/main/java/org/codehaus/groovy/control/ParserPlugin.java
+++ b/src/main/java/org/codehaus/groovy/control/ParserPlugin.java
@@ -18,19 +18,28 @@
*/
package org.codehaus.groovy.control;
+import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.syntax.ParserException;
import org.codehaus.groovy.syntax.Reduction;
+import org.codehaus.groovy.util.CharSequenceReader;
import java.io.Reader;
/**
- * A simple extension point to allow us to switch between the classic Groovy parser and the new Antlr based parser
- *
+ * A simple extension point to allow us to switch between the classic Groovy parser and the new Antlr based parser(s).
*/
public interface ParserPlugin {
Reduction parseCST(SourceUnit sourceUnit, Reader reader) throws CompilationFailedException;
ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException;
+
+ static ModuleNode buildAST(CharSequence source, GroovyClassLoader loader, CompilerConfiguration config, ErrorCollector errors) throws ParserException {
+ String scriptName = "Script" + System.nanoTime() + ".groovy";
+ SourceUnit sourceUnit = new SourceUnit(scriptName, source.toString(), config, loader, errors);
+
+ ParserPlugin parserPlugin = config.getPluginFactory().createParserPlugin();
+ return parserPlugin.buildAST(sourceUnit, loader, parserPlugin.parseCST(sourceUnit, new CharSequenceReader(source)));
+ }
}
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 865068b..697e0b4 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
@@ -31,13 +31,14 @@ import org.codehaus.groovy.ast.expr.ArrayExpression
import org.codehaus.groovy.ast.expr.BinaryExpression
import org.codehaus.groovy.ast.expr.ClosureExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
+import org.codehaus.groovy.ast.expr.DeclarationExpression
import org.codehaus.groovy.ast.expr.Expression
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.ast.tools.Antlr4Utils
-import org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.ast.stmt.ExpressionStatement
+import org.codehaus.groovy.control.ParserPlugin
import org.codehaus.groovy.control.ResolveVisitor
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.messages.SyntaxErrorMessage
@@ -173,7 +174,8 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
@CompileStatic
private static ClassNode buildNodeFromString(String option, TypeCheckingContext ctx) {
- ClassNode parsedNode = Antlr4Utils.parse(option, CompilerConfiguration.DEFAULT)
+ def moduleNode = ParserPlugin.buildAST("Dummy<$option> dummy;", ctx.compilationUnit.classLoader, ctx.compilationUnit.configuration, ctx.errorCollector)
+ ClassNode parsedNode = ((DeclarationExpression) ((ExpressionStatement) moduleNode.statementBlock.statements[0]).expression).leftExpression.type
ClassNode dummyClass = new ClassNode("dummy", 0, OBJECT_TYPE)
dummyClass.setModule(new ModuleNode(ctx.source))
MethodNode dummyMN = new MethodNode(
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 fa6aa7b..fa6b381 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,18 +18,10 @@
*/
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;
@@ -40,9 +32,6 @@ 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
@@ -88,55 +77,4 @@ 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(),
- "final " + typeStr + " v",
- compilerConfiguration,
- AccessController.doPrivileged((PrivilegedAction<GroovyClassLoader>) GroovyClassLoader::new),
- 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();
- }
}