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/05/23 21:20:05 UTC
[groovy] branch master updated: InvokerHelper#createScript makes
fewer assumtions about non-Script class
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 7a56d71 InvokerHelper#createScript makes fewer assumtions about non-Script class
7a56d71 is described below
commit 7a56d7130aaf7b5244fa5a82fa0505fb7509f51f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 23 16:19:40 2021 -0500
InvokerHelper#createScript makes fewer assumtions about non-Script class
---
.../org/codehaus/groovy/runtime/InvokerHelper.java | 39 +++----
src/test/gls/innerClass/InnerClassTest.groovy | 6 +-
src/test/groovy/bugs/Groovy5802Bug.groovy | 51 --------
.../codehaus/groovy/runtime/InvokerHelperTest.java | 129 ++++++++++++++-------
4 files changed, 110 insertions(+), 115 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java b/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
index 6d64276..7620b9b 100644
--- a/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
+++ b/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
@@ -76,8 +76,6 @@ import static java.lang.Math.max;
* A static helper class to make bytecode generation easier and act as a facade over the Invoker
*/
public class InvokerHelper {
- private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
-
public static final Object[] EMPTY_ARGS = {};
protected static final Object[] EMPTY_ARGUMENTS = EMPTY_ARGS;
protected static final Class[] EMPTY_TYPES = {};
@@ -230,7 +228,6 @@ public class InvokerHelper {
setProperty(object, property, newValue);
}
-
/**
* This is so we don't have to reorder the stack when we call this method.
* At some point a better name might be in order.
@@ -243,7 +240,6 @@ public class InvokerHelper {
return object.getProperty(property);
}
-
/**
* This is so we don't have to reorder the stack when we call this method.
* At some point a better name might be in order.
@@ -461,38 +457,33 @@ public class InvokerHelper {
if (Script.class.isAssignableFrom(scriptClass)) {
script = newScript(scriptClass, context);
} else {
- final GroovyObject object = (GroovyObject) scriptClass.getDeclaredConstructor().newInstance();
- // it could just be a class, so let's wrap it in a Script
- // wrapper; though the bindings will be ignored
+ // wrap call "ScriptClass.main(args)" with a Script instance
script = new Script(context) {
@Override
public Object run() {
- Object argsToPass = EMPTY_MAIN_ARGS;
+ Object[] mainArgs = {new String[0]};
try {
Object args = getProperty("args");
if (args instanceof String[]) {
- argsToPass = args;
+ mainArgs[0] = args;
}
- } catch (MissingPropertyException e) {
- // They'll get empty args since none exist in the context.
+ } catch (MissingPropertyException mpe) {
+ // call with empty array
}
- object.invokeMethod(MAIN_METHOD_NAME, argsToPass);
- return null;
+ return InvokerHelper.invokeStaticMethod(scriptClass, MAIN_METHOD_NAME, mainArgs);
}
};
- Map variables = context.getVariables();
- MetaClass mc = getMetaClass(object);
- for (Object o : variables.entrySet()) {
- Map.Entry entry = (Map.Entry) o;
- String key = entry.getKey().toString();
- // assume underscore variables are for the wrapper script
- setPropertySafe(key.startsWith("_") ? script : object, mc, key, entry.getValue());
- }
+
+ MetaClass smc = getMetaClass(scriptClass);
+ ((Map<?,?>) context.getVariables()).forEach((key, value) -> {
+ String name = key.toString();
+ if (!name.startsWith("_")) { // assume underscore variables are for the wrapper
+ setPropertySafe(scriptClass, smc, name, value);
+ }
+ });
}
} catch (Exception e) {
- throw new GroovyRuntimeException(
- "Failed to create Script instance for class: "
- + scriptClass + ". Reason: " + e, e);
+ throw new GroovyRuntimeException("Failed to create Script instance for class: " + scriptClass + ". Reason: " + e, e);
}
}
return script;
diff --git a/src/test/gls/innerClass/InnerClassTest.groovy b/src/test/gls/innerClass/InnerClassTest.groovy
index 2a5e340..c13cc5a 100644
--- a/src/test/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/gls/innerClass/InnerClassTest.groovy
@@ -1121,7 +1121,11 @@ final class InnerClassTest {
class A {
static field = 10
- void main(a) {
+ static main(args) {
+ new A().test()
+ }
+
+ void test() {
assert new C().m() == [10,12,14,16]
}
diff --git a/src/test/groovy/bugs/Groovy5802Bug.groovy b/src/test/groovy/bugs/Groovy5802Bug.groovy
deleted file mode 100644
index 4f33888..0000000
--- a/src/test/groovy/bugs/Groovy5802Bug.groovy
+++ /dev/null
@@ -1,51 +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 groovy.bugs
-
-import groovy.test.GroovyTestCase
-import org.codehaus.groovy.runtime.InvokerHelper
-
-class Groovy5802Bug extends GroovyTestCase {
-
- void testBindingVariablesSetPropertiesInSingleClassScripts() {
- def binding = new Binding(first: 'John', last: 'Smith')
- def saved = System.out
- def baos = new ByteArrayOutputStream()
- System.out = new PrintStream(baos)
- new GroovyShell(binding).parse('''
- class Person {
- static String first, last, result
- static void main(String[] args) { println "$first $last" }
- }
- ''').run()
- System.out = saved
- assert baos.toString().trim() == "John Smith"
- }
-
- void testInvokerHelperNotConfusedByScriptVariables() {
- InvokerHelper.createScript(MyList5802, new Binding('_': []))
- }
-
- void testMissingVariablesForSingleListClassScripts() {
- InvokerHelper.createScript(MyList5802, new Binding('x': []))
- }
-
-}
-
-class MyList5802 extends ArrayList {}
diff --git a/src/test/org/codehaus/groovy/runtime/InvokerHelperTest.java b/src/test/org/codehaus/groovy/runtime/InvokerHelperTest.java
index d80ae14..7dcd0cb 100644
--- a/src/test/org/codehaus/groovy/runtime/InvokerHelperTest.java
+++ b/src/test/org/codehaus/groovy/runtime/InvokerHelperTest.java
@@ -21,58 +21,109 @@ package org.codehaus.groovy.runtime;
import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
+import groovy.lang.GroovyShell;
import groovy.lang.Script;
-import junit.framework.TestCase;
+import org.junit.Test;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
-import static org.codehaus.groovy.runtime.InvokerHelper.initialCapacity;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+public final class InvokerHelperTest {
-public class InvokerHelperTest extends TestCase {
- private HashMap bindingVariables;
+ private final Map<String, Object> variables = new HashMap<>();
- protected void setUp() throws Exception {
- bindingVariables = new HashMap();
- bindingVariables.put("name", "hans");
+ @Test
+ public void testCreateScriptWithNullClass() {
+ Script script = InvokerHelper.createScript(null, new Binding(variables));
+
+ assertSame(variables, script.getBinding().getVariables());
}
- public void testCreateScriptWithNullClass() {
- Script script = InvokerHelper.createScript(null, new Binding(bindingVariables));
- assertEquals(bindingVariables, script.getBinding().getVariables());
+ @Test
+ public void testCreateScriptWithScriptClass() throws Exception {
+ try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
+ String controlProperty = "text", controlValue = "I am a script";
+ Class<?> scriptClass = classLoader.parseClass(new GroovyCodeSource(
+ controlProperty + " = '" + controlValue + "'", "testscript", "/groovy/shell"), false);
+
+ Script script = InvokerHelper.createScript(scriptClass, new Binding(variables));
+
+ assertSame(variables, script.getBinding().getVariables());
+
+ script.run();
+
+ assertEquals(controlValue, script.getProperty(controlProperty));
+ }
+ }
+
+ @Test // GROOVY-5802
+ public void testBindingVariablesSetPropertiesInSingleClassScripts() {
+ variables.put("first", "John");
+ variables.put("last", "Smith");
+
+ PrintStream sysout = System.out;
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String source =
+ "class Person {\n" +
+ " static String first, last, unused\n" +
+ " static main(args) { print \"$first $last\" }\n" +
+ "}\n";
+ new GroovyShell(new Binding(variables)).parse(source).run();
+
+ assertEquals("John Smith", baos.toString());
+ } finally {
+ System.setOut(sysout);
+ }
}
- public void testCreateScriptWithScriptClass() {
- GroovyClassLoader classLoader = new GroovyClassLoader();
- String controlProperty = "text";
- String controlValue = "I am a script";
- String code = controlProperty + " = '" + controlValue + "'";
- GroovyCodeSource codeSource = new GroovyCodeSource(code, "testscript", "/groovy/shell");
- Class scriptClass = classLoader.parseClass(codeSource, false);
- Script script = InvokerHelper.createScript(scriptClass, new Binding(bindingVariables));
- assertEquals(bindingVariables, script.getBinding().getVariables());
- script.run();
- assertEquals(controlValue, script.getProperty(controlProperty));
+ @Test // GROOVY-5802
+ public void testInvokerHelperNotConfusedByScriptVariables() {
+ variables.put("_", Collections.emptyList());
+
+ InvokerHelper.createScript(MyList5802.class, new Binding(variables));
}
+ @Test // GROOVY-5802
+ public void testMissingVariablesForSingleListClassScripts() {
+ variables.put("x", Collections.emptyList());
+
+ InvokerHelper.createScript(MyList5802.class, new Binding(variables));
+ }
+
+ @Test
public void testInitialCapacity() {
- assertEquals(16, initialCapacity(0));
- assertEquals(2, initialCapacity(1));
- assertEquals(4, initialCapacity(2));
- assertEquals(4, initialCapacity(3));
- assertEquals(8, initialCapacity(4));
- assertEquals(8, initialCapacity(5));
- assertEquals(8, initialCapacity(6));
- assertEquals(8, initialCapacity(7));
- assertEquals(16, initialCapacity(8));
- assertEquals(16, initialCapacity(9));
- assertEquals(16, initialCapacity(10));
- assertEquals(16, initialCapacity(11));
- assertEquals(16, initialCapacity(12));
- assertEquals(16, initialCapacity(13));
- assertEquals(16, initialCapacity(14));
- assertEquals(16, initialCapacity(15));
- assertEquals(32, initialCapacity(16));
- assertEquals(32, initialCapacity(17));
+ assertEquals(16, InvokerHelper.initialCapacity(0));
+ assertEquals( 2, InvokerHelper.initialCapacity(1));
+ assertEquals( 4, InvokerHelper.initialCapacity(2));
+ assertEquals( 4, InvokerHelper.initialCapacity(3));
+ assertEquals( 8, InvokerHelper.initialCapacity(4));
+ assertEquals( 8, InvokerHelper.initialCapacity(5));
+ assertEquals( 8, InvokerHelper.initialCapacity(6));
+ assertEquals( 8, InvokerHelper.initialCapacity(7));
+ assertEquals(16, InvokerHelper.initialCapacity(8));
+ assertEquals(16, InvokerHelper.initialCapacity(9));
+ assertEquals(16, InvokerHelper.initialCapacity(10));
+ assertEquals(16, InvokerHelper.initialCapacity(11));
+ assertEquals(16, InvokerHelper.initialCapacity(12));
+ assertEquals(16, InvokerHelper.initialCapacity(13));
+ assertEquals(16, InvokerHelper.initialCapacity(14));
+ assertEquals(16, InvokerHelper.initialCapacity(15));
+ assertEquals(32, InvokerHelper.initialCapacity(16));
+ assertEquals(32, InvokerHelper.initialCapacity(17));
+ }
+
+ //--------------------------------------------------------------------------
+
+ private static class MyList5802 extends ArrayList<Object> {
+ private static final long serialVersionUID = 0;
}
}