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 2021/02/09 20:33:50 UTC
[groovy] branch master updated: AstStringCompiler: close class
loader after compile
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
The following commit(s) were added to refs/heads/master by this push:
new 99c2804 AstStringCompiler: close class loader after compile
99c2804 is described below
commit 99c2804236f67ef2086fde3d63ae929b4f3d5ebb
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Feb 9 14:33:36 2021 -0600
AstStringCompiler: close class loader after compile
---
.../groovy/ast/builder/AstStringCompiler.java | 87 ++++++++++++----------
.../codehaus/groovy/antlr/AstBuilderTest.groovy | 33 +++++---
2 files changed, 68 insertions(+), 52 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/builder/AstStringCompiler.java b/src/main/java/org/codehaus/groovy/ast/builder/AstStringCompiler.java
index 368a28a..3c2115c 100644
--- a/src/main/java/org/codehaus/groovy/ast/builder/AstStringCompiler.java
+++ b/src/main/java/org/codehaus/groovy/ast/builder/AstStringCompiler.java
@@ -18,69 +18,74 @@
*/
package org.codehaus.groovy.ast.builder;
-import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.CompilerConfiguration;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
-import java.util.stream.Collectors;
+
+import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly;
/**
* This class handles converting Strings to ASTNode lists.
*/
public class AstStringCompiler {
+
/**
- * Performs the String source to {@link java.util.List} of {@link ASTNode}.
+ * Compiles the specified source code and returns its statement block and
+ * any declared types.
*
* @param script
* a Groovy script in String form
- * @param compilePhase
- * the int based CompilePhase to compile it to.
- * @param statementsOnly
- * @return {@link java.util.List} of {@link ASTNode}
+ *
+ * @since 3.0.0
*/
- public List<ASTNode> compile(String script, CompilePhase compilePhase, boolean statementsOnly) {
- final String scriptClassName = makeScriptClassName();
- GroovyCodeSource codeSource = new GroovyCodeSource(script, scriptClassName + ".groovy", "/groovy/script");
- CompilationUnit cu = new CompilationUnit(CompilerConfiguration.DEFAULT, codeSource.getCodeSource(),
- AccessController.doPrivileged((PrivilegedAction<GroovyClassLoader>) GroovyClassLoader::new));
- cu.addSource(codeSource.getName(), script);
- cu.compile(compilePhase.getPhaseNumber());
-
- // collect all the ASTNodes into the result, possibly ignoring the script body if desired
- List<ASTNode> result = cu.getAST().getModules().stream().reduce(new LinkedList<>(), (acc, node) -> {
- BlockStatement statementBlock = node.getStatementBlock();
- if (null != statementBlock) {
- acc.add(statementBlock);
- }
- acc.addAll(
- node.getClasses().stream()
- .filter(c -> !(statementsOnly && scriptClassName.equals(c.getName())))
- .collect(Collectors.toList())
- );
-
- return acc;
- }, (o1, o2) -> o1);
-
- return result;
+ public List<ASTNode> compile(final String script) {
+ return compile(script, CompilePhase.CONVERSION, true);
}
/**
- * Performs the String source to {@link java.util.List} of statement {@link ASTNode}.
+ * Compiles the specified source code and returns its statement block, the
+ * script class (if desired) and any declared types.
*
- * @param script a Groovy script in String form
- * @return {@link java.util.List} of statement {@link ASTNode}
- * @since 3.0.0
+ * @param script
+ * a Groovy script in String form
+ * @param compilePhase
+ * the last compilation phase to complete
+ * @param statementsOnly
+ * if {@code true}, exclude the script class from the result
+ *
+ * @since 1.7.0
*/
- public List<ASTNode> compile(String script) {
- return this.compile(script, CompilePhase.CONVERSION, true);
+ public List<ASTNode> compile(final String script, final CompilePhase compilePhase, final boolean statementsOnly) {
+ String scriptClassName = makeScriptClassName();
+ GroovyCodeSource codeSource = new GroovyCodeSource(script, scriptClassName + ".groovy", "/groovy/script");
+ CompilationUnit cu = new CompilationUnit(CompilerConfiguration.DEFAULT, codeSource.getCodeSource(), null);
+ try {
+ cu.addSource(codeSource.getName(), script);
+ cu.compile(compilePhase.getPhaseNumber());
+ } finally {
+ closeQuietly(cu.getClassLoader());
+ }
+
+ List<ASTNode> nodes = new ArrayList<>();
+ for (ModuleNode mn : cu.getAST().getModules()) {
+ ASTNode statementBlock = mn.getStatementBlock();
+ if (statementBlock != null) {
+ nodes.add(statementBlock);
+ }
+ for (ClassNode cn : mn.getClasses()) {
+ if (!(statementsOnly && scriptClassName.equals(cn.getName()))) {
+ nodes.add(cn);
+ }
+ }
+ }
+ return nodes;
}
private static String makeScriptClassName() {
diff --git a/src/test/org/codehaus/groovy/antlr/AstBuilderTest.groovy b/src/test/org/codehaus/groovy/antlr/AstBuilderTest.groovy
index a9e8fed..dfdeb7f 100644
--- a/src/test/org/codehaus/groovy/antlr/AstBuilderTest.groovy
+++ b/src/test/org/codehaus/groovy/antlr/AstBuilderTest.groovy
@@ -23,6 +23,8 @@ import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.InnerClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.builder.AstBuilder
+import org.codehaus.groovy.ast.stmt.BlockStatement
+import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.stmt.Statement
import static org.codehaus.groovy.control.CompilePhase.CONVERSION
@@ -32,23 +34,32 @@ import static org.codehaus.groovy.control.CompilePhase.CONVERSION
*/
class AstBuilderTest extends GroovyTestCase {
- void testInnerClassLineNumbers() {
+ void testStatementsOnly() {
+ def nodes = new AstBuilder().buildFromString CONVERSION, '''
+ println 'hello world'
+ '''
+
+ assert nodes.size() == 1
+ assert nodes[0] instanceof BlockStatement
+ assert nodes[0].statements[0] instanceof ExpressionStatement
+ }
- def result = new AstBuilder().buildFromString CONVERSION, false, '''
+ void testInnerClassLineNumbers() {
+ def nodes = new AstBuilder().buildFromString CONVERSION, '''
new Object() {
}
'''
- assert result[2].getClass() == InnerClassNode
- assert result[2].lineNumber == 2
- assert result[2].lastLineNumber == 4
- assert result[2].columnNumber == 26
- assert result[2].lastColumnNumber == 14
+ assert nodes[1].getClass() == InnerClassNode
+ assert nodes[1].lineNumber == 2
+ assert nodes[1].lastLineNumber == 4
+ assert nodes[1].columnNumber == 26
+ assert nodes[1].lastColumnNumber == 14
}
void testEnumLineNumbers() {
- def result = new AstBuilder().buildFromString CONVERSION, false, '''
+ def result = new AstBuilder().buildFromString CONVERSION, '''
enum Color {
}
@@ -62,15 +73,15 @@ class AstBuilderTest extends GroovyTestCase {
}
void testStatementAfterLabel() {
- def result = new AstBuilder().buildFromString CONVERSION, false, '''
+ def nodes = new AstBuilder().buildFromString CONVERSION, false, '''
def method() {
label:
assert i == 9
}
'''
- assert result[1].getClass() == ClassNode
- MethodNode method = result[1].getMethods('method')[0]
+ assert nodes[1].getClass() == ClassNode
+ MethodNode method = nodes[1].getMethods('method')[0]
Statement statement = method.code.statements[0]
assert statement.lineNumber == 4
assert statement.lastLineNumber == 4