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 2022/12/26 22:49:37 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-10105: streamline `GroovyStarter` -> `Groovysh` -> user's script
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 3a46f5f24b GROOVY-10105: streamline `GroovyStarter` -> `Groovysh` -> user's script
3a46f5f24b is described below
commit 3a46f5f24bf93953f16cae74d10b07547e393ea4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Dec 26 15:55:46 2022 -0600
GROOVY-10105: streamline `GroovyStarter` -> `Groovysh` -> user's script
2_5_X backport
---
.../org/codehaus/groovy/tools/GroovyStarter.java | 55 ++--
.../codehaus/groovy/tools/LoaderConfiguration.java | 16 +-
.../java/org/codehaus/groovy/tools/RootLoader.java | 98 +++---
.../codehaus/groovy/tools/shell/Groovysh.groovy | 229 ++++++-------
.../tools/shell/InteractiveShellRunner.groovy | 100 +++---
.../codehaus/groovy/tools/shell/Interpreter.groovy | 70 ++--
.../org/codehaus/groovy/tools/shell/Main.groovy | 25 +-
.../shell/util/DefaultCommandsRegistrar.groovy | 57 ++--
.../groovy/tools/shell/CompletorTestSupport.groovy | 41 +--
.../groovy/tools/shell/ErrorDisplayTest.groovy | 51 ++-
.../groovy/tools/shell/ImportCompletorTest.groovy | 22 +-
.../groovy/tools/shell/ShellRunnerTest.groovy | 86 +++--
.../tools/shell/ShellRunnerTestSupport.groovy | 34 +-
.../completion/GroovySyntaxCompletorTest.groovy | 361 ++++++++-------------
14 files changed, 558 insertions(+), 687 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java b/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
index 08f8f1cf08..a76ed224ee 100644
--- a/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
+++ b/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
@@ -19,10 +19,10 @@
package org.codehaus.groovy.tools;
import java.io.FileInputStream;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Arrays;
/**
* Helper class to initialize the Groovy runtime.
@@ -33,12 +33,19 @@ public class GroovyStarter {
System.out.println("possible programs are 'groovyc','groovy','console', and 'groovysh'");
System.exit(1);
}
-
-
- public static void rootLoader(String args[]) {
+
+ public static void main(String[] args) {
+ try {
+ rootLoader(args);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ public static void rootLoader(String[] args) {
String conf = System.getProperty("groovy.starter.conf",null);
final LoaderConfiguration lc = new LoaderConfiguration();
-
+
// evaluate parameters
boolean hadMain=false, hadConf=false, hadCP=false;
int argsOffset = 0;
@@ -69,7 +76,7 @@ public class GroovyStarter {
hadConf=true;
} else {
break;
- }
+ }
}
// this allows to override the commandline conf
@@ -80,10 +87,9 @@ public class GroovyStarter {
if (lc.getMainClass()==null && conf==null) {
exit("no configuration file or main class specified");
}
-
- // copy arguments for main class
- String[] newArgs = new String[args.length-argsOffset];
- System.arraycopy(args, 0 + argsOffset, newArgs, 0, newArgs.length);
+
+ // copy arguments for main class
+ String[] mainArgs = Arrays.copyOfRange(args, argsOffset, args.length);
// load configuration file
if (conf!=null) {
try {
@@ -95,39 +101,32 @@ public class GroovyStarter {
}
// create loader and execute main class
ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<RootLoader>() {
+ @Override
public RootLoader run() {
return new RootLoader(lc);
}
});
- Method m=null;
+ Method m = null;
try {
- Class c = loader.loadClass(lc.getMainClass());
+ Class<?> c = loader.loadClass(lc.getMainClass());
m = c.getMethod("main", String[].class);
- } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e1) {
- exit(e1);
+ } catch (ReflectiveOperationException | SecurityException e2) {
+ exit(e2);
}
try {
- m.invoke(null, new Object[]{newArgs});
- } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e3) {
+ m.invoke(null, new Object[]{mainArgs});
+ } catch (ReflectiveOperationException | IllegalArgumentException e3) {
exit(e3);
}
}
-
+
private static void exit(Exception e) {
e.printStackTrace();
System.exit(1);
}
-
- private static void exit(String msg) {
- System.err.println(msg);
+
+ private static void exit(String text) {
+ System.err.println(text);
System.exit(1);
}
-
- public static void main(String args[]) {
- try {
- rootLoader(args);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
}
diff --git a/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java b/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
index a95258c807..d36f92eb55 100644
--- a/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
+++ b/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
@@ -19,7 +19,6 @@
package org.codehaus.groovy.tools;
import org.apache.groovy.util.SystemUtil;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import java.io.BufferedReader;
import java.io.File;
@@ -142,12 +141,17 @@ public class LoaderConfiguration {
if (requireMain && main == null) throw new IOException("missing main class definition in config file");
if (!configScripts.isEmpty()) {
- System.setProperty("groovy.starter.configscripts", DefaultGroovyMethods.join((Iterable)configScripts, ","));
+ StringBuilder sb = new StringBuilder();
+ for (String configScript : configScripts) {
+ if (sb.length() > 0) sb.append(',');
+ sb.append(configScript);
+ }
+ System.setProperty("groovy.starter.configscripts", sb.toString());
}
}
/*
- * Expands the properties inside the given string to it's values.
+ * Expands the properties inside the given string to their values.
*/
private static String assignProperties(String str) {
int propertyIndexStart = 0, propertyIndexEnd = 0;
@@ -170,7 +174,7 @@ public class LoaderConfiguration {
if (propertyIndexStart == -1) break;
result.append(str, propertyIndexEnd, propertyIndexStart);
- propertyIndexEnd = str.indexOf("}", propertyIndexStart);
+ propertyIndexEnd = str.indexOf('}', propertyIndexStart);
if (propertyIndexEnd == -1) break;
String propertyKey = str.substring(propertyIndexStart + 2, propertyIndexEnd);
@@ -192,9 +196,9 @@ public class LoaderConfiguration {
}
if (propertyIndexStart == -1 || propertyIndexStart >= str.length()) {
- result.append(str.substring(propertyIndexEnd));
+ result.append(str, propertyIndexEnd, str.length());
} else if (propertyIndexEnd == -1) {
- result.append(str.substring(propertyIndexStart));
+ result.append(str, propertyIndexStart, str.length());
}
return result.toString();
diff --git a/src/main/java/org/codehaus/groovy/tools/RootLoader.java b/src/main/java/org/codehaus/groovy/tools/RootLoader.java
index dfd42ad7c2..9d4e3f853d 100644
--- a/src/main/java/org/codehaus/groovy/tools/RootLoader.java
+++ b/src/main/java/org/codehaus/groovy/tools/RootLoader.java
@@ -23,12 +23,11 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
* This ClassLoader should be used as root of class loaders. Any
- * RootLoader does have it's own classpath. When searching for a
+ * RootLoader does have its own classpath. When searching for a
* class or resource this classpath will be used. Parent
* Classloaders are ignored first. If a class or resource
* can't be found in the classpath of the RootLoader, then parent is
@@ -45,7 +44,7 @@ import java.util.Map;
* classloader does know a class which depends on a class only
* a child of this loader does know, then you won't be able to
* load the class. To load the class the child is not allowed
- * to redirect it's search for the class to the parent first.
+ * to redirect its search for the class to the parent first.
* That way the child can load the class. If the child does not
* have all classes to do this, this fails of course.
* <p>
@@ -73,58 +72,61 @@ import java.util.Map;
* instance will solve that problem.
*/
public class RootLoader extends URLClassLoader {
- private static final URL[] EMPTY_URL_ARRAY = new URL[0];
- private final Map<String, Class> customClasses = new HashMap<>();
+
private static final String ORG_W3C_DOM_NODE = "org.w3c.dom.Node";
+ private final Map<String, Class<?>> customClasses = new HashMap<>();
/**
- * constructs a new RootLoader without classpath
+ * Constructs a {@code RootLoader} without classpath.
*
* @param parent the parent Loader
*/
- public RootLoader(ClassLoader parent) {
- this(EMPTY_URL_ARRAY, parent);
+ public RootLoader(final ClassLoader parent) {
+ this(new URL[0], parent);
}
/**
- * constructs a new RootLoader with a parent loader and an
- * array of URLs as classpath
+ * Constructs a {@code RootLoader} with a parent loader and an array of URLs
+ * as its classpath.
*/
- public RootLoader(URL[] urls, ClassLoader parent) {
+ public RootLoader(final URL[] urls, final ClassLoader parent) {
super(urls, parent);
- // major hack here...!
+ // major hack here!!
try {
customClasses.put(ORG_W3C_DOM_NODE, super.loadClass(ORG_W3C_DOM_NODE, false));
- } catch (Exception e) { /* ignore */ }
+ } catch (Exception e) {
+ // ignore
+ }
}
private static ClassLoader chooseParent() {
ClassLoader cl = RootLoader.class.getClassLoader();
- if (cl != null) return cl;
- return ClassLoader.getSystemClassLoader();
+ if (cl == null)
+ cl = ClassLoader.getSystemClassLoader();
+ return cl;
}
/**
- * constructs a new RootLoader with a {@link LoaderConfiguration}
- * object which holds the classpath
+ * Constructs a {@code RootLoader} with a {@link LoaderConfiguration} object
+ * which holds the classpath.
*/
- public RootLoader(LoaderConfiguration lc) {
+ public RootLoader(final LoaderConfiguration lc) {
this(chooseParent());
+
Thread.currentThread().setContextClassLoader(this);
- URL[] urls = lc.getClassPathUrls();
- for (URL url : urls) {
+
+ for (URL url : lc.getClassPathUrls()) {
addURL(url);
}
// TODO M12N eventually defer this until later when we have a full Groovy
// environment and use normal Grape.grab()
String groovyHome = System.getProperty("groovy.home");
- List<String> grabUrls = lc.getGrabUrls();
- for (String grabUrl : grabUrls) {
- Map<String, Object> grabParts = GrapeUtil.getIvyParts(grabUrl);
- String group = grabParts.get("group").toString();
- String module = grabParts.get("module").toString();
- String name = grabParts.get("module").toString() + "-" + grabParts.get("version") + ".jar";
- File jar = new File(groovyHome + "/repo/" + group + "/" + module + "/jars/" + name);
+ for (String url : lc.getGrabUrls()) {
+ Map<String, Object> grabParts = GrapeUtil.getIvyParts(url);
+ String group = (String) grabParts.get("group");
+ String module = (String) grabParts.get("module");
+ String version = (String) grabParts.get("version");
+ File jar = new File(groovyHome + "/repo/" + group + "/" + module + "/jars/" + module + "-" + version + ".jar");
try {
addURL(jar.toURI().toURL());
} catch (MalformedURLException e) {
@@ -134,47 +136,53 @@ public class RootLoader extends URLClassLoader {
}
/**
- * loads a class using the name of the class
+ * {@inheritDoc}
*/
- protected synchronized Class loadClass(final String name, boolean resolve) throws ClassNotFoundException {
- Class c = this.findLoadedClass(name);
+ @Override
+ protected synchronized Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ Class<?> c = findLoadedClass(name);
if (c != null) return c;
c = customClasses.get(name);
if (c != null) return c;
try {
- c = oldFindClass(name);
- } catch (ClassNotFoundException cnfe) {
- // IGNORE
+ c = super.findClass(name);
+ } catch (ClassNotFoundException e) {
+ // ignore
}
- if (c == null) c = super.loadClass(name, resolve);
+ if (c == null)
+ c = super.loadClass(name, resolve);
- if (resolve) resolveClass(c);
+ if (resolve)
+ resolveClass(c);
return c;
}
/**
- * returns the URL of a resource, or null if it is not found
+ * {@inheritDoc}
*/
- public URL getResource(String name) {
+ @Override
+ public URL getResource(final String name) {
URL url = findResource(name);
- if (url == null) url = super.getResource(name);
+ if (url == null)
+ url = super.getResource(name);
return url;
}
/**
- * adds an url to the classpath of this classloader
+ * {@inheritDoc}
*/
- public void addURL(URL url) {
+ @Override
+ public void addURL(final URL url) {
super.addURL(url);
}
- private Class oldFindClass(String name) throws ClassNotFoundException {
- return super.findClass(name);
- }
-
- protected Class findClass(String name) throws ClassNotFoundException {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Class<?> findClass(final String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy
index db152a8371..901f8fbe15 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy
@@ -19,6 +19,8 @@
package org.codehaus.groovy.tools.shell
import antlr.TokenStreamException
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import jline.Terminal
import jline.WindowsTerminal
@@ -44,19 +46,19 @@ import org.fusesource.jansi.AnsiRenderer
import java.util.regex.Pattern
+import static org.codehaus.groovy.control.CompilerConfiguration.DEFAULT
+
/**
* An interactive shell for evaluating Groovy code from the command-line (aka. groovysh).
*
* The set of available commands can be modified by placing a file in the classpath named
* <code>org/codehaus/groovy/tools/shell/commands.xml</code>
*
- * See {@link XmlCommandRegistrar}
+ * @see XmlCommandRegistrar
*/
+@AutoFinal @CompileStatic
class Groovysh extends Shell {
-
- private static final MessageSource messages = new MessageSource(Groovysh)
-
private static final Pattern TYPEDEF_PATTERN = ~'^\\s*((?:public|protected|private|static|abstract|final)\\s+)*(?:class|enum|interface).*'
private static final Pattern METHODDEF_PATTERN = ~'^\\s*((?:public|protected|private|static|abstract|final|synchronized)\\s+)*[a-zA-Z_.]+[a-zA-Z_.<>]+\\s+[a-zA-Z_]+\\(.*'
@@ -71,6 +73,9 @@ class Groovysh extends Shell {
// after how many prefix characters we start displaying all metaclass methods
public static final String METACLASS_COMPLETION_PREFIX_LENGTH_PREFERENCE_KEY = 'meta-completion-prefix-length'
+ private static final MessageSource messages = new MessageSource(Groovysh)
+
+ //
final BufferManager buffers = new BufferManager()
@@ -87,57 +92,54 @@ class Groovysh extends Shell {
FileHistory history
- boolean historyFull // used as a workaround for GROOVY-2177
+ boolean historyFull // used as a workaround for GROOVY-2177
- String evictedLine // remembers the command which will get evicted if history is full
+ String evictedLine // remembers the command which will get evicted if history is full
PackageHelper packageHelper
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar) {
- this(classLoader, binding, io, registrar, null)
+ private static Closure createDefaultRegistrar(ClassLoader classLoader) {
+ return { Groovysh groovysh ->
+ URL xmlCommandResource = groovysh.getClass().getResource('commands.xml')
+ if (xmlCommandResource != null) {
+ def registrar = new XmlCommandRegistrar(groovysh, classLoader)
+ registrar.register(xmlCommandResource)
+ } else {
+ def registrar = new DefaultCommandsRegistrar(groovysh)
+ registrar.register()
+ }
+ }
}
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar, CompilerConfiguration configuration) {
- this(classLoader, binding, io, registrar, configuration, new Interpreter(classLoader, binding, configuration))
- }
-
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar, CompilerConfiguration configuration, Interpreter interpreter) {
+ //--------------------------------------------------------------------------
+
+ Groovysh(ClassLoader classLoader, Binding binding, IO io, Closure registrar, CompilerConfiguration configuration, Interpreter interpreter) {
super(io)
assert classLoader
assert binding
- def actualRegistrar = registrar ?: createDefaultRegistrar(classLoader)
- parser = new Parser()
+ def theRegistrar = registrar ?: createDefaultRegistrar(classLoader)
interp = interpreter
- actualRegistrar.call(this)
- this.packageHelper = new PackageHelperImpl(classLoader)
+ parser = new Parser()
+ theRegistrar.call(this)
+ packageHelper = new PackageHelperImpl(classLoader)
}
- private static Closure createDefaultRegistrar(final ClassLoader classLoader) {
- return {Groovysh shell ->
- URL xmlCommandResource = getClass().getResource('commands.xml')
- if (xmlCommandResource != null) {
- def r = new XmlCommandRegistrar(shell, classLoader)
- r.register(xmlCommandResource)
- } else {
- new DefaultCommandsRegistrar(shell).register()
- }
- }
+ Groovysh(ClassLoader classLoader, Binding binding, IO io, Closure registrar = null, CompilerConfiguration configuration = null) {
+ this(classLoader, binding, io, registrar, configuration, new Interpreter(classLoader, binding, configuration))
}
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io) {
- this(classLoader, binding, io, null)
- }
+ // ClassLoader,Binding,IO variants (drop left-to-right)
- Groovysh(final Binding binding, final IO io) {
- this(Thread.currentThread().contextClassLoader, binding, io)
+ Groovysh(Binding binding, IO io) {
+ this(Thread.currentThread().getContextClassLoader(), binding, io)
}
- Groovysh(final IO io) {
- this(new Binding(), io)
+ Groovysh(IO io, CompilerConfiguration cc) {
+ this(Thread.currentThread().getContextClassLoader(), new Binding(), io, null, cc)
}
- Groovysh(final IO io, CompilerConfiguration configuration) {
- this(Thread.currentThread().contextClassLoader, new Binding(), io, null, configuration)
+ Groovysh(IO io) {
+ this(new Binding(), io)
}
Groovysh() {
@@ -152,11 +154,11 @@ class Groovysh extends Shell {
* Execute a single line, where the line may be a command or Groovy code (complete or incomplete).
*/
@Override
- Object execute(final String line) {
+ Object execute(String line) {
assert line != null
// Ignore empty lines
- if (line.trim().size() == 0) {
+ if (line.trim().isEmpty()) {
return null
}
@@ -228,16 +230,15 @@ class Groovysh extends Shell {
* @param strings
* @return
*/
- @CompileStatic
- static boolean isTypeOrMethodDeclaration(final List<String> buffer) {
- final String joined = buffer.join('')
+ static boolean isTypeOrMethodDeclaration(List<String> buffer) {
+ String joined = buffer.join('')
return joined.matches(TYPEDEF_PATTERN) || joined.matches(METHODDEF_PATTERN)
}
/*
* to simulate an interpreter mode, this method wraps the statements into a try/finally block that
* stores bound variables like unbound variables
*/
- private Object evaluateWithStoredBoundVars(String importsSpec, final List<String> current) {
+ private Object evaluateWithStoredBoundVars(String importsSpec, List<String> current) {
Object result
String variableBlocks = null
// To make groovysh behave more like an interpreter, we need to retrieve all bound
@@ -254,7 +255,7 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
})
}
// Evaluate the current buffer w/imports and dummy statement
- List<String> buff;
+ List<String> buff
if (variableBlocks) {
buff = [importsSpec] + ['try {', 'true'] + current + ['} finally {' + variableBlocks + '}']
} else {
@@ -263,23 +264,21 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
setLastResult(result = interp.evaluate(buff))
if (variableBlocks) {
- Map<String, Object> boundVarValues = interp.context.getVariable(COLLECTED_BOUND_VARS_MAP_VARNAME)
+ def boundVarValues = (Map<String, Object>) interp.context.getVariable(COLLECTED_BOUND_VARS_MAP_VARNAME)
boundVarValues.each({ String name, Object value -> interp.context.setVariable(name, value) })
}
return result
}
-
-
- protected Object executeCommand(final String line) {
+ protected Object executeCommand(String line) {
return super.execute(line)
}
/**
* Display the given buffer.
*/
- void displayBuffer(final List buffer) {
+ void displayBuffer(List buffer) {
assert buffer
buffer.eachWithIndex { line, index ->
@@ -297,16 +296,15 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Prompt
//
- private final AnsiRenderer prompt = new AnsiRenderer()
-
- /*
- Builds the command prompt name in 1 of 3 ways:
- 1. Checks the groovysh.prompt property passed into groovysh script. -Dgroovysh.prompt="hello"
- 2. Checks an environment variable called GROOVYSH_PROMPT. export GROOVYSH_PROMPT
- 3. If no value is defined returns the default groovy shell prompt.
-
- The code will always assume you want the line number in the prompt. To implement differently overhead the render
- prompt variable.
+ /**
+ * Builds the command prompt name in 1 of 3 ways:
+ * <ol>
+ * <li>Checks the groovysh.prompt property passed into groovysh script: {@code -Dgroovysh.prompt="hello"}
+ * <li>Checks an environment variable called GROOVYSH_PROMPT: {@code export GROOVYSH_PROMPT}
+ * <li>If no value is defined returns the default groovy shell prompt.
+ * </ol>
+ * The code will always assume you want the line number in the prompt. To
+ * implement differently overhead the render prompt variable.
*/
private String buildPrompt() {
def lineNum = formatLineNumber(buffers.current().size())
@@ -340,27 +338,27 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// not sure whether the same Lexer instance could be reused.
def lexer = CurlyCountingGroovyLexer.createGroovyLexer(src.toString())
-
// read all tokens
try {
- while (lexer.nextToken().getType() != CurlyCountingGroovyLexer.EOF) {}
+ while (lexer.nextToken().getType() != CurlyCountingGroovyLexer.EOF) {
+ }
} catch (TokenStreamException e) {
- // pass
+ // ignore
}
- int parenIndent = (lexer.getParenLevel()) * indentSize
+ int curlyIndent = lexer.getParenLevel() * indentSize
// dedent after closing brackets
- return ' ' * Math.max(parenIndent, 0)
+ return ' ' * Math.max(curlyIndent, 0)
}
- public String renderPrompt() {
- return prompt.render( buildPrompt() )
+ String renderPrompt() {
+ return AnsiRenderer.render(buildPrompt())
}
/**
* Format the given number suitable for rendering as a line number column.
*/
- protected String formatLineNumber(final int num) {
+ protected String formatLineNumber(int num) {
assert num >= 0
// Make a %03d-like string for the line number
@@ -378,29 +376,25 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
/**
- * Loads file from within user groovy state directory
- * @param filename
+ * Loads file from within user groovy state directory.
*/
- protected void loadUserScript(final String filename) {
+ @CompileDynamic
+ protected void loadUserScript(String filename) {
assert filename
- File file = new File(getUserStateDirectory(), filename)
-
+ def file = new File(getUserStateDirectory(), filename)
if (file.exists()) {
- Command command = registry[LoadCommand.COMMAND_NAME] as Command
-
+ def command = registry[LoadCommand.COMMAND_NAME] as Command
if (command) {
log.debug("Loading user-script: $file")
// Disable the result hook for profile scripts
def previousHook = resultHook
resultHook = { result -> /* nothing */}
-
try {
command.load(file.toURI().toURL())
}
finally {
- // Restore the result hook
resultHook = previousHook
}
} else {
@@ -413,30 +407,30 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Recording
//
- protected void maybeRecordInput(final String line) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ protected void maybeRecordInput(String line) {
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
record.recordInput(line)
}
}
- protected void maybeRecordResult(final Object result) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ protected void maybeRecordResult(Object result) {
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
record.recordResult(result)
}
}
protected void maybeRecordError(Throwable cause) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
+ Throwable error
if (getPreference(SANITIZE_PREFERENCE_KEY, 'false')) {
- cause = StackTraceUtils.deepSanitize(cause)
+ error = StackTraceUtils.deepSanitize(cause)
+ } else {
+ error = cause
}
- record.recordError(cause)
+ record.recordError(error)
}
}
@@ -444,7 +438,7 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Hooks
//
- final Closure defaultResultHook = {Object result ->
+ final Closure defaultResultHook = { Object result ->
boolean showLastResult = !io.quiet && (io.verbose || getPreference(SHOW_LAST_RESULT_PREFERENCE_KEY, 'false'))
if (showLastResult) {
// avoid String.valueOf here because it bypasses pretty-printing of Collections,
@@ -455,12 +449,12 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
Closure resultHook = defaultResultHook
- private void setLastResult(final Object result) {
+ private void setLastResult(Object result) {
if (resultHook == null) {
throw new IllegalStateException('Result hook is not set')
}
- resultHook.call((Object)result)
+ resultHook.call(result)
interp.context['_'] = result
@@ -470,16 +464,16 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
final Closure defaultErrorHook = { Throwable cause ->
assert cause != null
- if (log.debug || ! (cause instanceof CompilationFailedException)) {
+ if (log.debug || !(cause instanceof CompilationFailedException)) {
// For CompilationErrors, the Exception Class is usually not useful to the user
io.err.println("@|bold,red ERROR|@ ${cause.getClass().name}:")
}
if (cause instanceof MultipleCompilationErrorsException) {
- Writer data = new org.apache.groovy.io.StringBuilderWriter();
- PrintWriter writer = new PrintWriter(data);
+ Writer data = new org.apache.groovy.io.StringBuilderWriter()
+ PrintWriter writer = new PrintWriter(data)
ErrorCollector collector = ((MultipleCompilationErrorsException) cause).getErrorCollector()
- Iterator<Message> msgIterator = collector.getErrors().iterator()
+ def msgIterator = (Iterator<Message>) collector.getErrors().iterator()
while (msgIterator.hasNext()) {
Message errorMsg = msgIterator.next()
errorMsg.write(writer)
@@ -491,7 +485,6 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
} else {
io.err.println("@|bold,red ${cause.message}|@")
-
maybeRecordError(cause)
if (log.debug) {
@@ -500,13 +493,8 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
else {
boolean sanitize = getPreference(SANITIZE_PREFERENCE_KEY, 'false')
-
// Sanitize the stack trace unless we are in verbose mode, or the user has request otherwise
- if (!io.verbose && sanitize) {
- cause = StackTraceUtils.deepSanitize(cause)
- }
-
- def trace = cause.stackTrace
+ def trace = (sanitize && !io.verbose ? StackTraceUtils.deepSanitize(cause) : cause).stackTrace
def buff = new StringBuilder()
@@ -542,13 +530,13 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
// protected for mocking in tests
- protected String getPreference(final String key, final String theDefault) {
+ protected String getPreference(String key, String theDefault) {
return Preferences.get(key, theDefault)
}
Closure errorHook = defaultErrorHook
- private void displayError(final Throwable cause) {
+ private void displayError(Throwable cause) {
if (errorHook == null) {
throw new IllegalStateException('Error hook is not set')
}
@@ -563,38 +551,36 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
/**
- * Run Interactive Shell with optional initial script and files to load
- */
- int run(final String evalString, final List<String> filenames) {
+ * Run the Interactive Shell with optional initial script and files to load.
+ */
+ int run(String evalString, List<String> filenames) {
List<String> startCommands = []
-
- if (evalString != null && evalString.trim().size() > 0) {
+ if (evalString?.trim()) {
startCommands.add(evalString)
}
- if (filenames != null && filenames.size() > 0) {
- startCommands.addAll(filenames.collect({String it -> "${LoadCommand.COMMAND_NAME} $it"}))
+ if (filenames) {
+ filenames.each {
+ startCommands.add("${LoadCommand.COMMAND_NAME} $it".toString())
+ }
}
return run(startCommands.join('\n'))
}
/**
- * Run Interactive Shell with initial command
+ * Run the Interactive Shell with initial command.
*/
- int run(final String commandLine) {
+ int run(String commandLine) {
def code
-
try {
loadUserScript('groovysh.profile')
loadUserScript('groovysh.rc')
// Setup the interactive runner
- runner = new InteractiveShellRunner(
- this,
- this.&renderPrompt as Closure)
+ runner = new InteractiveShellRunner(this, this.&renderPrompt)
// if args were passed in, just execute as a command
// (but cygwin gives an empty string, so ignore that)
- if (commandLine != null && commandLine.trim().size() > 0) {
+ if (commandLine?.trim()) {
runner.wrappedInputStream.insert(commandLine + '\n')
}
@@ -611,18 +597,14 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// And let 'er rip... :-)
runner.run()
-
code = 0
} catch (ExitNotification n) {
- log.debug("Exiting w/code: ${n.code}")
-
code = n.code
- }
- catch (Throwable t) {
+ log.debug("Exiting w/code: $code")
+ } catch (Throwable t) {
+ code = 1
io.err.println(messages.format('info.fatal', t))
t.printStackTrace(io.err)
-
- code = 1
}
assert code != null // This should never happen
@@ -630,12 +612,11 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
return code
}
-
/**
* maybe displays log information and a welcome message
* @param term
*/
- public void displayWelcomeBanner(InteractiveShellRunner runner) {
+ void displayWelcomeBanner(InteractiveShellRunner runner) {
if (!log.debug && io.quiet) {
// nothing to do here
return
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/InteractiveShellRunner.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/InteractiveShellRunner.groovy
index 0733ec9bc7..ee16251c3d 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/InteractiveShellRunner.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/InteractiveShellRunner.groovy
@@ -18,9 +18,13 @@
*/
package org.codehaus.groovy.tools.shell
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
import jline.console.ConsoleReader
import jline.console.completer.AggregateCompleter
import jline.console.completer.CandidateListCompletionHandler
+import jline.console.completer.Completer
import jline.console.completer.CompletionHandler
import jline.console.history.FileHistory
import org.codehaus.groovy.tools.shell.completion.CustomClassSyntaxCompletor
@@ -37,55 +41,54 @@ import org.codehaus.groovy.tools.shell.util.WrappedInputStream
/**
* Support for running a {@link Shell} interactively using the JLine library.
*/
-class InteractiveShellRunner
- extends ShellRunner
- implements Runnable
-{
- ConsoleReader reader
+@AutoFinal @CompileStatic
+class InteractiveShellRunner extends ShellRunner implements Runnable {
+ ConsoleReader reader
final Closure prompt
-
final CommandsMultiCompleter completer
- WrappedInputStream wrappedInputStream
+ WrappedInputStream wrappedInputStream
- InteractiveShellRunner(final Groovysh shell, final Closure prompt) {
+ @CompileDynamic
+ InteractiveShellRunner(Groovysh shell, Closure prompt) {
super(shell)
this.prompt = prompt
this.wrappedInputStream = new WrappedInputStream(shell.io.inputStream)
this.reader = new ConsoleReader(wrappedInputStream, shell.io.outputStream)
- CompletionHandler currentCompletionHandler = this.reader.getCompletionHandler()
+ CompletionHandler currentCompletionHandler = reader.getCompletionHandler()
if (currentCompletionHandler instanceof CandidateListCompletionHandler) {
- // have to downcast because methods not part of the interface
- ((CandidateListCompletionHandler) currentCompletionHandler).setStripAnsi(true)
- ((CandidateListCompletionHandler) currentCompletionHandler).setPrintSpaceAfterFullCompletion(false)
+ currentCompletionHandler.setStripAnsi(true)
+ currentCompletionHandler.setPrintSpaceAfterFullCompletion(false)
}
-
// expand events ia an advanced feature of JLine that clashes with Groovy syntax (e.g. invoke "2!=3")
- this.reader.expandEvents = false
-
+ reader.expandEvents = false
// complete groovysh commands, display, import, ... as first word in line
- this.completer = new CommandsMultiCompleter()
- reader.addCompleter(this.completer)
+ completer = new CommandsMultiCompleter()
- CustomClassSyntaxCompletor classnameCompletor = new CustomClassSyntaxCompletor(shell)
+ def classnameCompletor = new CustomClassSyntaxCompletor(shell)
- reader.addCompleter(new GroovySyntaxCompletor(shell,
+ reader.addCompleter(completer)
+ reader.addCompleter(new GroovySyntaxCompletor(
+ shell,
new ReflectionCompletor(shell),
classnameCompletor,
- [new KeywordSyntaxCompletor(),
+ [
+ new KeywordSyntaxCompletor(),
new VariableSyntaxCompletor(shell),
classnameCompletor,
- new ImportsSyntaxCompletor(shell)],
- new FileNameCompleter(false)))
+ new ImportsSyntaxCompletor(shell)
+ ],
+ new FileNameCompleter(false)
+ ))
}
@Override
void run() {
- for (Command command in shell.registry.commands()) {
+ for (command in shell.registry.commands()) {
completer.add(command)
}
@@ -97,20 +100,7 @@ class InteractiveShellRunner
super.run()
}
- void setHistory(final FileHistory history) {
- reader.history = history
- def dir = history.file.parentFile
-
- if (!dir.exists()) {
- dir.mkdirs()
-
- log.debug("Created base directory for history file: $dir")
- }
-
- log.debug("Using history file: $history.file")
- }
-
- @Override
+ @Override @CompileDynamic
protected String readLine() {
try {
if (Boolean.valueOf(Preferences.get(Groovysh.AUTOINDENT_PREFERENCE_KEY))) {
@@ -135,18 +125,18 @@ class InteractiveShellRunner
@Override
protected boolean work() {
- boolean result= super.work()
+ boolean result = super.work()
adjustHistory()
result
}
private void adjustHistory() {
- // we save the evicted line in casesomeone wants to use it with history recall
+ // we save the evicted line in case someone wants to use it with history recall
if (shell instanceof Groovysh) {
def history = shell.history
- shell.historyFull = (history != null) && (history.size() >= history.maxSize)
- if (shell.historyFull) {
+ shell.historyFull = history != null && history.size() >= history.maxSize
+ if (shell.isHistoryFull()) {
def first = history.first()
if (first) {
shell.evictedLine = first.value()
@@ -155,21 +145,33 @@ class InteractiveShellRunner
}
}
+ void setHistory(FileHistory history) {
+ reader.history = history
+ def dir = history.file.parentFile
+
+ if (!dir.exists()) {
+ dir.mkdirs()
+
+ log.debug("Created base directory for history file: $dir")
+ }
+
+ log.debug("Using history file: $history.file")
+ }
}
/**
* Completer for interactive shells.
*/
-class CommandsMultiCompleter
- extends AggregateCompleter
-{
- protected final Logger log = Logger.create(this.class)
+@AutoFinal @CompileStatic
+class CommandsMultiCompleter extends AggregateCompleter {
+
+ protected final Logger log = Logger.create(getClass())
- List/*<Completer>*/ list = []
+ List<Completer> list = []
- private boolean dirty = false
+ private boolean dirty
- def add(final Command command) {
+ def add(Command command) {
assert command
//
@@ -196,7 +198,7 @@ class CommandsMultiCompleter
}
@Override
- int complete(final String buffer, final int pos, final List cand) {
+ int complete(String buffer, int pos, List cand) {
assert buffer != null
//
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Interpreter.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Interpreter.groovy
index bb0bd1d826..1304071b20 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Interpreter.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Interpreter.groovy
@@ -18,29 +18,31 @@
*/
package org.codehaus.groovy.tools.shell
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.runtime.InvokerHelper
import org.codehaus.groovy.runtime.MethodClosure
import org.codehaus.groovy.tools.shell.util.Logger
-import java.lang.reflect.Method
+interface Evaluator {
+ Object evaluate(Collection<String> strings)
+}
/**
* Helper to interpret a source buffer.
*/
-class Interpreter implements Evaluator
-{
+@AutoFinal @CompileStatic
+class Interpreter implements Evaluator {
+
static final String SCRIPT_FILENAME = 'groovysh_evaluate'
- private final Logger log = Logger.create(this.class)
+ private final Logger log = Logger.create(getClass())
private final GroovyShell shell
- Interpreter(final ClassLoader classLoader, final Binding binding) {
- this(classLoader, binding, null)
- }
-
- Interpreter(final ClassLoader classLoader, final Binding binding, CompilerConfiguration configuration) {
+ Interpreter(ClassLoader classLoader, Binding binding, CompilerConfiguration configuration = null) {
assert classLoader
assert binding
if (configuration != null) {
@@ -50,35 +52,36 @@ class Interpreter implements Evaluator
}
}
+ GroovyClassLoader getClassLoader() {
+ return shell.getClassLoader()
+ }
+
Binding getContext() {
// GROOVY-9584: leave as call to getter not property access to avoid potential context variable in binding
return shell.getContext()
}
- GroovyClassLoader getClassLoader() {
- return shell.classLoader
- }
-
GroovyShell getShell() {
return shell
}
- @Override
- def evaluate(final Collection<String> buffer) {
+ //--------------------------------------------------------------------------
+
+ @Override @CompileDynamic
+ Object evaluate(Collection<String> buffer) {
assert buffer
- def source = buffer.join(Parser.NEWLINE)
+ String source = buffer.join(Parser.NEWLINE)
- def result
+ Object result = null
- Class type
+ Class type = null
try {
- Script script = shell.parse(source, SCRIPT_FILENAME)
- type = script.getClass()
-
+ type = shell.parseClass(new GroovyCodeSource(source, SCRIPT_FILENAME, GroovyShell.DEFAULT_CODE_BASE))
+ Script script = InvokerHelper.createScript(type, context)
log.debug("Compiled script: $script")
- if (type.declaredMethods.any {Method it -> it.name == 'main' }) {
+ if (type.getDeclaredMethods().any { it.name == 'main' }) {
result = script.run()
}
@@ -86,28 +89,23 @@ class Interpreter implements Evaluator
log.debug("Evaluation result: ${InvokerHelper.toString(result)} (${result?.getClass()})")
// Keep only the methods that have been defined in the script
- type.declaredMethods.each { Method m ->
- if (!(m.name in [ 'main', 'run' ] || m.name.startsWith('super$') || m.name.startsWith('class$') || m.name.startsWith('$'))) {
- log.debug("Saving method definition: $m.name")
-
- context["${m.name}"] = new MethodClosure(type.newInstance(), m.name)
+ type.getDeclaredMethods().each { m ->
+ String name = m.name
+ if (!(name == 'main' || name == 'run' || name.startsWith('super$') || name.startsWith('class$') || name.startsWith('$'))) {
+ log.debug("Saving script method definition: $name")
+ context[name] = new MethodClosure(script, name)
}
}
- }
- finally {
- // Remove the script class generated
+ } finally {
+ // Remove the generated script class
if (type?.name) {
- classLoader.removeClassCacheEntry(type?.name)
+ classLoader.removeClassCacheEntry(type.name)
}
- // Remove the inline closures from the cache as well
+ // Remove the inline closures as well
classLoader.removeClassCacheEntry('$_run_closure')
}
return result
}
}
-
-interface Evaluator {
- def evaluate(final Collection<String> buffer)
-}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Main.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Main.groovy
index 8957a67ca3..8470137be6 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Main.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Main.groovy
@@ -20,6 +20,9 @@ package org.codehaus.groovy.tools.shell
import groovy.cli.picocli.CliBuilder
import groovy.cli.picocli.OptionAccessor
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
import jline.TerminalFactory
import jline.UnixTerminal
import jline.UnsupportedTerminal
@@ -46,6 +49,7 @@ import static org.apache.groovy.util.SystemUtil.setSystemPropertyFrom
*
* Main CLI entry-point for <tt>groovysh</tt>.
*/
+@AutoFinal @CompileStatic
class Main {
final Groovysh groovysh
@@ -69,7 +73,8 @@ class Main {
* create a Main instance, configures it according to CLI arguments, and starts the shell.
* @param main must have a Groovysh member that has an IO member.
*/
- static void main(final String[] args) {
+ @CompileDynamic
+ static void main(String[] args) {
MessageSource messages = new MessageSource(Main)
CliBuilder cli = new CliBuilder(usage: 'groovysh [options] [...]', stopAtNonOption: false,
header: messages['cli.option.header'])
@@ -147,10 +152,13 @@ class Main {
if (options.e) {
evalString = options.getOptionValue('e')
}
- def configuration = new CompilerConfiguration(System.getProperties())
- configuration.setParameters((boolean) options.hasOption("pa"))
- List<String> filenames = options.arguments()
+ start(io, evalString, options.arguments(), options.hasOption('pa'))
+ }
+
+ private static void start(IO io, String evalString, List<String> filenames, boolean parameters) {
+ def configuration = new CompilerConfiguration(System.getProperties())
+ configuration.setParameters(parameters)
Main main = new Main(io, configuration)
main.startGroovysh(evalString, filenames)
}
@@ -181,10 +189,8 @@ class Main {
}
}
-
- SecurityManager psm = System.getSecurityManager()
+ final SecurityManager psm = System.getSecurityManager()
System.setSecurityManager(new NoExitSecurityManager())
-
try {
code = shell.run(evalString, filenames)
}
@@ -203,6 +209,7 @@ class Main {
* @param type: one of 'auto', 'unix', ('win', 'windows'), ('false', 'off', 'none')
* @param suppressColor only has effect when ansi is enabled
*/
+ @AutoFinal(enabled=false)
static void setTerminalType(String type, boolean suppressColor) {
assert type != null
@@ -230,6 +237,7 @@ class Main {
// Should never happen
throw new IllegalArgumentException("Invalid Terminal type: $type")
}
+
if (enableAnsi) {
installAnsi() // must be called before IO(), since it modifies System.in
Ansi.enabled = !suppressColor
@@ -252,8 +260,7 @@ class Main {
}
@Deprecated
- static void setSystemProperty(final String nameValue) {
+ static void setSystemProperty(String nameValue) {
setSystemPropertyFrom(nameValue)
}
}
-
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/DefaultCommandsRegistrar.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/DefaultCommandsRegistrar.groovy
index af5b6622af..1d9deefb30 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/DefaultCommandsRegistrar.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/util/DefaultCommandsRegistrar.groovy
@@ -40,49 +40,44 @@ import org.codehaus.groovy.tools.shell.commands.SetCommand
import org.codehaus.groovy.tools.shell.commands.ShowCommand
/**
- * Registers {@link Command} classes from an XML file like:
- * <commands>
- * <command>org.codehaus.groovy.tools.shell.commands.HelpCommand</command>
- * ...
- * </commands>
+ * Registers default {@link Command} instances.
*/
-class DefaultCommandsRegistrar
-{
+class DefaultCommandsRegistrar {
private final Shell shell
DefaultCommandsRegistrar(final Shell shell) {
assert shell != null
-
this.shell = shell
}
void register() {
+ List<Command> commands = [
+ new HelpCommand(shell),
+ new ExitCommand(shell),
+ new ImportCommand(shell),
+ new DisplayCommand(shell),
+ new ClearCommand(shell),
+ new ShowCommand(shell),
+ new InspectCommand(shell),
+ new PurgeCommand(shell),
+ new EditCommand(shell),
+ new LoadCommand(shell),
+ new SaveCommand(shell),
+ new RecordCommand(shell),
+ new HistoryCommand(shell),
+ new AliasCommand(shell),
+ new SetCommand(shell),
+ new GrabCommand(shell),
+ new RegisterCommand(shell),
+ ]
- for (Command classname in [
- new HelpCommand(shell),
- new ExitCommand(shell),
- new ImportCommand(shell),
- new DisplayCommand(shell),
- new ClearCommand(shell),
- new ShowCommand(shell),
- new InspectCommand(shell),
- new PurgeCommand(shell),
- new EditCommand(shell),
- new LoadCommand(shell),
- new SaveCommand(shell),
- new RecordCommand(shell),
- new HistoryCommand(shell),
- new AliasCommand(shell),
- new SetCommand(shell),
- new GrabCommand(shell),
- // does not do anything
- //new ShadowCommand(shell),
- new RegisterCommand(shell),
- new DocCommand(shell)
- ]) {
- shell.register(classname)
+ if (!Boolean.getBoolean('groovysh.disableDocCommand')) {
+ commands.add(new DocCommand(shell))
}
+ for (command in commands) {
+ shell.register(command)
+ }
}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/CompletorTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/CompletorTestSupport.groovy
index 7b5db874c7..31973b07c5 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/CompletorTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/CompletorTestSupport.groovy
@@ -21,53 +21,36 @@ package org.codehaus.groovy.tools.shell
import groovy.mock.interceptor.MockFor
import org.codehaus.groovy.tools.shell.completion.IdentifierCompletor
import org.codehaus.groovy.tools.shell.completion.ReflectionCompletor
-import org.codehaus.groovy.tools.shell.util.PackageHelper
import org.codehaus.groovy.tools.shell.util.PackageHelperImpl
abstract class CompletorTestSupport extends GroovyTestCase {
- BufferManager bufferManager = new BufferManager()
- IO testio
ByteArrayOutputStream mockOut
ByteArrayOutputStream mockErr
- MockFor groovyshMocker
- MockFor packageHelperMocker
- PackageHelper mockPackageHelper
+ IO testio
MockFor reflectionCompletorMocker
-
+ MockFor packageHelperMocker
MockFor idCompletorMocker
+ MockFor groovyshMocker
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
mockOut = new ByteArrayOutputStream()
-
mockErr = new ByteArrayOutputStream()
+ testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
- testio = new IO(
- new ByteArrayInputStream(),
- mockOut,
- mockErr)
reflectionCompletorMocker = new MockFor(ReflectionCompletor)
-
+ packageHelperMocker = new MockFor(PackageHelperImpl)
idCompletorMocker = new MockFor(IdentifierCompletor)
groovyshMocker = new MockFor(Groovysh)
- groovyshMocker.demand.getClass(0..1) { Groovysh }
- groovyshMocker.demand.createDefaultRegistrar { { shell -> null } }
- groovyshMocker.demand.getIo(0..2) { testio }
- packageHelperMocker = new MockFor(PackageHelperImpl)
- def registry = new CommandRegistry()
- groovyshMocker.demand.getRegistry(0..1) { registry }
- packageHelperMocker.demand.getContents(6) { ['java', 'test'] }
- groovyshMocker.demand.getIo(0..2) { testio }
- for (i in 1..19) {
- groovyshMocker.demand.getIo(0..1) { testio }
- groovyshMocker.demand.add(0..1) {}
- groovyshMocker.demand.getIo(0..1) { testio }
- }
- groovyshMocker.demand.getRegistry(0..1) { registry }
- groovyshMocker.demand.getBuffers(0..2) {bufferManager}
+ // no-arg constructor
+ groovyshMocker.demand.getClass( 1) { Groovysh }
+ groovyshMocker.demand.getIo(0..21) { testio }
+ groovyshMocker.demand.register(18) { it }
+ // new command
+ groovyshMocker.demand.getIo( 0..3) { testio }
}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ErrorDisplayTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ErrorDisplayTest.groovy
index 6245048b8b..0ba00d9338 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ErrorDisplayTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ErrorDisplayTest.groovy
@@ -18,56 +18,43 @@
*/
package org.codehaus.groovy.tools.shell
-import jline.console.ConsoleReader
import jline.console.completer.CandidateListCompletionHandler
-
-class ErrorDisplayTest extends ShellRunnerTestSupport {
+final class ErrorDisplayTest extends ShellRunnerTestSupport {
void testInput() {
- readerStubber.demand.readLine { 'foo' }
+ readerStubber.demand.readLine {'foo'}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use {
- readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, { '>' })
- shellRunner.reader = readerStub
- // assert no exception
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
shellRunner.run()
+ // no exception
}
}
}
void testError() {
- readerStubber.demand.readLine { throw new StringIndexOutOfBoundsException() }
+ readerStubber.demand.readLine {throw new StringIndexOutOfBoundsException()}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use {
- readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, { '>' })
- shellRunner.reader = readerStub
- // assert no exception
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
shellRunner.run()
+ // no exception
}
}
}
void testError2() {
- readerStubber.demand.readLine { throw new Throwable('MockException') }
+ readerStubber.demand.readLine {throw new Throwable('MockException')}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use { readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, {'>'})
- shellRunner.reader = readerStub
- // assert no exception
- shellRunner.run()
- }}
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
+ shellRunner.run()
+ // no exception
+ }
+ }
}
-
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ImportCompletorTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ImportCompletorTest.groovy
index 7104d444db..c7d5eca445 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ImportCompletorTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ImportCompletorTest.groovy
@@ -17,22 +17,23 @@
* under the License.
*/
package org.codehaus.groovy.tools.shell
+
import groovy.mock.interceptor.MockFor
-import jline.console.completer.ArgumentCompleter
import jline.console.completer.Completer
-import jline.console.completer.NullCompleter
-import jline.console.completer.StringsCompleter
import org.codehaus.groovy.tools.shell.commands.ImportCommand
import org.codehaus.groovy.tools.shell.commands.ImportCompleter
import org.codehaus.groovy.tools.shell.util.PackageHelper
import org.codehaus.groovy.tools.shell.util.Preferences
+
/**
* as opposed to MockFor, traditional custom mocking allows @CompileStatic for the class under Test
*/
class MockPackageHelper implements PackageHelper {
+
Set<String> mockContents
+
MockPackageHelper(Collection<String> mockContents) {
- this.mockContents = new HashSet<String>(mockContents)
+ this.mockContents = mockContents.toSet()
}
@Override
@@ -41,16 +42,16 @@ class MockPackageHelper implements PackageHelper {
}
@Override
- void reset() { }
+ void reset() {
+ }
}
-class ImportCompleterUnitTest extends GroovyTestCase {
+final class ImportCompleterUnitTest extends GroovyTestCase {
private MockFor preferencesMocker
-
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
preferencesMocker = new MockFor(Preferences)
}
@@ -138,7 +139,6 @@ class ImportCompleterUnitTest extends GroovyTestCase {
assert !'java.util.T'.matches(ImportCompleter.LOWERCASE_IMPORT_ITEM_PATTERN)
}
-
private void assertCompletionCandidatesMatch(
final PackageHelper packageHelper,
final String buffer,
@@ -278,7 +278,9 @@ class ImportCompleterUnitTest extends GroovyTestCase {
}
}
-class ImportCompleterTest extends CompletorTestSupport {
+final class ImportCompleterTest extends CompletorTestSupport {
+
+ private PackageHelper mockPackageHelper
void testEmpty() {
mockPackageHelper = new MockPackageHelper(['java', 'test'])
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTest.groovy
index 41715d8392..cd92f26518 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTest.groovy
@@ -23,45 +23,51 @@ import jline.console.ConsoleReader
import jline.console.completer.CandidateListCompletionHandler
import org.codehaus.groovy.tools.shell.util.Preferences
-class ShellRunnerTest extends GroovyTestCase {
+final class ShellRunnerTest extends GroovyTestCase {
private Groovysh groovysh
+ private MockFor readerMocker
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
ByteArrayOutputStream mockOut = new ByteArrayOutputStream()
ByteArrayOutputStream mockErr = new ByteArrayOutputStream()
+ IO testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
- IO testio = new IO(new ByteArrayInputStream(),
- mockOut,
- mockErr)
groovysh = new Groovysh(testio)
+
+ readerMocker = new MockFor(ConsoleReader)
+ readerMocker.demand.getCompletionHandler(1) {new CandidateListCompletionHandler(stripAnsi: true)}
+ readerMocker.demand.setExpandEvents {}
+ readerMocker.demand.addCompleter(2) {}
}
+ //--------------------------------------------------------------------------
+
void testReadLineIndentPreferenceOff() {
groovysh.buffers.buffers.add(['Foo {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'false'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
+
assertEquals(0, runner.wrappedInputStream.inserted.available())
}}
}
void testReadLineIndentNone() {
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
+
assertEquals(0, runner.wrappedInputStream.inserted.available())
}}
}
@@ -70,13 +76,13 @@ class ShellRunnerTest extends GroovyTestCase {
groovysh.buffers.buffers.add(['Foo {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
+
assertEquals(groovysh.indentSize, runner.wrappedInputStream.inserted.available())
}}
}
@@ -84,51 +90,39 @@ class ShellRunnerTest extends GroovyTestCase {
void testReadLineIndentTwo() {
groovysh.buffers.buffers.add(['Foo { {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo { {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo { {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
+
assertEquals(groovysh.indentSize * 2, runner.wrappedInputStream.inserted.available())
}}
}
-
- private MockFor primedMockForConsoleReader() {
- def readerMocker = new MockFor(ConsoleReader)
- CandidateListCompletionHandler clch = new CandidateListCompletionHandler()
- clch.stripAnsi = true
- readerMocker.demand.getCompletionHandler(1) {clch}
- readerMocker.demand.setExpandEvents {}
- readerMocker.demand.addCompleter(2) {}
- readerMocker
- }
}
class ShellRunnerTest2 extends GroovyTestCase {
void testReadLinePaste() {
- ByteArrayOutputStream mockOut = new ByteArrayOutputStream()
- ByteArrayOutputStream mockErr = new ByteArrayOutputStream()
-
- IO testio = new IO(new ByteArrayInputStream('Some Clipboard Content'.bytes),
- mockOut,
- mockErr)
- Groovysh groovysh = new Groovysh(testio)
+ Groovysh groovysh = new Groovysh(new IO(new ByteArrayInputStream('Some Clipboard Content'.bytes),
+ new ByteArrayOutputStream(), new ByteArrayOutputStream()))
groovysh.buffers.buffers.add(['Foo { {'])
groovysh.buffers.select(1)
+ MockFor preferencesMocker = new MockFor(Preferences)
+ preferencesMocker.demand.get(1) {'true'}
MockFor readerMocker = new MockFor(ConsoleReader)
readerMocker.demand.getCompletionHandler {new CandidateListCompletionHandler()}
readerMocker.demand.setExpandEvents {}
readerMocker.demand.addCompleter(2) {}
readerMocker.demand.readLine(1) {'Foo { {'}
- MockFor preferencesMocker = new MockFor(Preferences)
- preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
+
assertEquals(0, runner.wrappedInputStream.inserted.available())
}}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTestSupport.groovy
index d74c6f38e0..16669c362a 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/ShellRunnerTestSupport.groovy
@@ -23,41 +23,39 @@ import groovy.mock.interceptor.StubFor
import jline.console.ConsoleReader
/**
- * Support for testing {@link Command} instances.
+ * Support for testing {@link ShellRunner} instances.
*/
abstract class ShellRunnerTestSupport extends GroovyTestCase {
- protected IO testio
protected BufferedOutputStream mockOut
protected BufferedOutputStream mockErr
+ protected IO testio
protected MockFor shellMocker
protected StubFor readerStubber
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
+
mockOut = new BufferedOutputStream(new ByteArrayOutputStream())
mockErr = new BufferedOutputStream(new ByteArrayOutputStream())
testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
testio.verbosity = IO.Verbosity.QUIET
- // setup mock and stub with calls expected from InteractiveShellRunner Constructor
shellMocker = new MockFor(Groovysh)
- // when run with compileStatic
- shellMocker.demand.getClass(0..1) {Groovysh}
- shellMocker.demand.createDefaultRegistrar(1) { {Shell shell -> null} }
+ // Groovysh constructor
+ shellMocker.demand.getClass( 1) { Groovysh }
+ shellMocker.demand.getIo(0..21) { testio }
+ shellMocker.demand.register(18) { it }
+ // InteractiveShellRunner constructor
shellMocker.demand.getIo(2) { testio }
- shellMocker.demand.getRegistry(1) {new Object() {def commands() {[]} }}
- shellMocker.demand.getHistory(1) {new Serializable(){def size() {0}; def getMaxSize() {1}}}
- shellMocker.demand.setHistoryFull(1) {}
- shellMocker.demand.getHistoryFull(1) {false}
- // adding number of commands from xml file
- for (i in 1..19) {
- shellMocker.demand.getIo(0..1) { testio }
- shellMocker.demand.add(0..1) { testio }
- shellMocker.demand.getIo(0..1) { testio }
- }
+ // InteractiveShellRunner run
+ shellMocker.demand.getRegistry(0..1) { new CommandRegistry() }
+ // InteractiveShellRunner adjustHistory
+ shellMocker.demand.getHistory(0..1) { null }
+ shellMocker.demand.setHistoryFull(0..1) { }
+ shellMocker.demand.isHistoryFull(0..1) { }
readerStubber = new StubFor(ConsoleReader)
readerStubber.demand.setExpandEvents {}
@@ -66,7 +64,5 @@ abstract class ShellRunnerTestSupport extends GroovyTestCase {
readerStubber.demand.addCompleter {}
readerStubber.demand.printNewline {}
readerStubber.demand.addCompleter {}
- shellMocker.demand.getIo(0..1) { testio }
}
-
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/completion/GroovySyntaxCompletorTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/completion/GroovySyntaxCompletorTest.groovy
index b7df08779e..0abe1d8ab4 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/completion/GroovySyntaxCompletorTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/codehaus/groovy/tools/shell/completion/GroovySyntaxCompletorTest.groovy
@@ -19,205 +19,156 @@
package org.codehaus.groovy.tools.shell.completion
import groovy.mock.interceptor.MockFor
+import org.codehaus.groovy.tools.shell.BufferManager
import org.codehaus.groovy.tools.shell.CommandRegistry
import org.codehaus.groovy.tools.shell.CompletorTestSupport
import org.codehaus.groovy.tools.shell.Groovysh
-import org.codehaus.groovy.tools.shell.commands.ImportCommand
-class GroovySyntaxCompletorTest extends CompletorTestSupport {
+final class GroovySyntaxCompletorTest extends CompletorTestSupport {
- void testEmpty() {
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
+ private final BufferManager bufferManager = new BufferManager()
+ private final List<CharSequence> candidates = []
+
+ private int runTest(String buffer, int cursor = buffer.length(), FileNameCompleter fileNameCompleter = null) {
+ if (buffer) {
+ def registry = new CommandRegistry()
+ groovyshMocker.demand.getRegistry(1) { registry }
+ groovyshMocker.demand.getBuffers(0..1) { bufferManager }
+ }
+
+ int result = Integer.MIN_VALUE
groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- assert -1 == completor.complete('', 0, [])
+ Groovysh groovysh = new Groovysh()
+ IdentifierCompletor identifierCompletor = idCompletorMocker.proxyDelegateInstance()
+ ReflectionCompletor reflectionCompletor = reflectionCompletorMocker.proxyInstance(groovysh)
+ GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovysh, reflectionCompletor, identifierCompletor, [identifierCompletor], fileNameCompleter)
+
+ result = completor.complete(buffer, cursor, candidates)
}
+ return result
+ }
+
+ void testEmpty() {
+ int result = runTest('')
+
+ assert result == -1
+ assert candidates.isEmpty()
}
void testIdentifier() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['jav']); candidates << 'javup'; candidates << 'java.lang.String' ; true}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'jav'
- // in the shell, only Classes in the default package occur,but well...
- assert 0 == completor.complete(buffer, buffer.length(), candidates)
- assert ['javup', 'java.lang.String'] == candidates
- }
+
+ int result = runTest('jav')
+
+ assert result == 0
+ assert candidates == ['javup', 'java.lang.String']
}
void testIdentifierAfterLCurly() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['{', 'jav']); candidates << 'javup'; candidates << 'java.lang.String' ; true}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = '{jav'
- // in the shell, only Classes in the default package occur,but well...
- assert 1 == completor.complete(buffer, buffer.length(), candidates)
- assert ['javup', 'java.lang.String'] == candidates
- }
+
+ int result = runTest('{jav')
+
+ assert result == 1
+ assert candidates == ['javup', 'java.lang.String']
}
void testMember() {
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Math', '.', 'ma']); candidates << 'max('; 5}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'Math.ma'
- assert 5 == completor.complete(buffer, buffer.length(), candidates)
- assert ['max('] == candidates
- }
+
+ int result = runTest('Math.ma')
+
+ assert result == 5
+ assert candidates == ['max(']
}
void testMemberOptionalDot() {
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Math', '?.', 'ma']); candidates << 'max('; 6}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'Math?.ma'
- assert 6 == completor.complete(buffer, buffer.length(), candidates)
- assert ['max('] == candidates
- }
+
+ int result = runTest('Math?.ma')
+
+ assert result == 6
+ assert candidates == ['max(']
}
void testMemberSpreadDot() {
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['[', 'foo', ']', '*.', 'len']); candidates << 'length()'; 9}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = '[\'foo\']*.len'
- assert 9 == completor.complete(buffer, buffer.length(), candidates)
- assert ['length()'] == candidates
- }
+
+ int result = runTest('[\'foo\']*.len')
+
+ assert result == 9
+ assert candidates == ['length()']
}
void testMemberAfterMethod() {
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Fo', '.', 'ba', '(', ')', '.', 'xyz']); candidates << 'xyzabc'; 0}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'Fo.ba().xyz'
- // xyz cannot be not a var here
- assert 0 == completor.complete(buffer, buffer.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ // xyz cannot be not a var here
+ int result = runTest('Fo.ba().xyz')
+
+ assert result == 0
+ assert candidates == ['xyzabc']
}
void testIdentfierAfterDotAfterParens() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Foo', '.', 'bar', '(', 'xyz']); candidates << 'xyzabc'; true}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'Foo.bar(xyz'
- assert 8 == completor.complete(buffer, buffer.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ int result = runTest('Foo.bar(xyz')
+
+ assert result == 8
+ assert candidates == ['xyzabc']
}
void testIndentifierAfterParensBeforeDot() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Foo', '.', 'bar', '(', 'xyz']); candidates << 'xyzabc'; true}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- // cursor is BEFORE dot
- assert 8 == completor.complete('Foo.bar(xyz.', 'Foo.bar(xyz'.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ int result = runTest('Foo.bar(xyz.', 'Foo.bar(xyz'.length()) // cursor is BEFORE dot
+
+ assert result == 8
+ assert candidates == ['xyzabc']
}
void testDoubleIdentifier() {
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'String jav'
- assert -1 == completor.complete(buffer, buffer.length(), candidates)
- assert [] == candidates
- }
+ int result = runTest('String jav')
+
+ assert result == -1
+ assert candidates == []
}
void testInfixKeyword() {
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'class Foo ext'
- assert 10 == completor.complete(buffer, buffer.length(), candidates)
- assert ['extends'] == candidates
- }
+ int result = runTest('class Foo ext')
+
+ assert result == 10
+ assert candidates == ['extends']
}
void testInstanceof() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['x', 'instanceof', 'P']); candidates << 'Property'; 13}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'x instanceof P'
- assert 13 == completor.complete(buffer, buffer.length(), candidates)
- assert 'Property' in candidates
- }
- }
+ int result = runTest('x instanceof P')
+ assert result == 13
+ assert candidates.contains('Property')
+ }
void testAfterSemi() {
// evaluation of all is dangerous, but the reflectionCompletor has to deal with this
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['deletehardDisk', '(', ')', ';', 'foo', '.', 'subs']); candidates << 'substring('; 22}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- // mock doing the right thing
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'deletehardDisk(); foo.subs'
- assert 22 == completor.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+ int result = runTest('deletehardDisk(); foo.subs')
+
+ assert result == 22
+ assert candidates == ['substring(']
}
void testAfterOperator() {
@@ -225,106 +176,76 @@ class GroovySyntaxCompletorTest extends CompletorTestSupport {
reflectionCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['a', '=', 'foo', '.', 'subs']); candidates << 'substring('; 9}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- // mock doing the right thing
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'a = foo.subs'
- assert 9 == completor.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+ int result = runTest('a = foo.subs')
+
+ assert result == 9
+ assert candidates == ['substring(']
}
void testDontEvaluateAfterCommand() {
- CommandRegistry registry = new CommandRegistry()
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- // mock asserting nothing gets evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- // import command prevents reflection completion
- registry.register(new ImportCommand(groovyshMock))
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'import foo'
- assert -1 == completor.complete(buffer, buffer.length(), candidates)
- assert [] == candidates
- }
+ // import command prevents reflection completion
+ int result = runTest('import foo')
+
+ assert result == -1
+ assert candidates == []
}
void _disabled_testAfterGString() { // should we prohibit this?
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- // mock asserting GString is not evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = '"\${foo.delete()}".subs'
- assert candidates == [] && -1 == completor.complete(buffer, buffer.length(), candidates)
- }
+ int result = runTest('"\${foo.delete()}".subs') // GString not evaluated
+
+ assert result == -1
+ assert candidates == []
}
void testInStringFilename() {
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- MockFor filenameCompletorMocker = new MockFor(FileNameCompleter)
- String linestart = /foo('/ // ends with single hyphen
+ def filenameCompleterMocker = new MockFor(FileNameCompleter)
+ String linestart = "foo('" // ends with apostrophe
String pathstart = '/usr/foobar'
- String buffer = linestart + pathstart
- filenameCompletorMocker.demand.complete(1) {bufferline, cursor, candidates ->
- assert(bufferline == pathstart)
- assert(cursor == pathstart.length())
- candidates << 'foobar'; 5}
- groovyshMocker.use { filenameCompletorMocker.use {
- FileNameCompleter mockFileComp = new FileNameCompleter()
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], mockFileComp)
- def candidates = []
- assert 'foo(\'/usr/'.length() == completor.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }}
+
+ filenameCompleterMocker.demand.complete(1) { bufferline, cursor, candidates ->
+ assert bufferline == pathstart
+ assert cursor == pathstart.length()
+ candidates << 'foobar'
+ 5
+ }
+ filenameCompleterMocker.use {
+ String buffer = linestart + pathstart
+ int result = runTest(buffer, buffer.length(), new FileNameCompleter())
+
+ assert result == "foo('/usr/".length()
+ assert candidates == ['foobar']
+ }
}
void testInStringFilenameBlanks() {
- // test with blanks (non-tokens) before the first hyphen
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- MockFor filenameCompletorMocker = new MockFor(FileNameCompleter)
- String linestart = 'x = \'' // ends with single hyphen
+ // test with blanks (non-tokens) before the apostrophe
+ def filenameCompleterMocker = new MockFor(FileNameCompleter)
+ String linestart = 'x = \'' // ends with apostrophe
String pathstart = '/usr/foobar'
- String buffer = linestart + pathstart
- filenameCompletorMocker.demand.complete(1) {bufferline, cursor, candidates ->
+
+ filenameCompleterMocker.demand.complete(1) {bufferline, cursor, candidates ->
assert bufferline == pathstart
assert cursor == pathstart.length()
- candidates << 'foobar'; 5}
- groovyshMocker.use { filenameCompletorMocker.use {
- FileNameCompleter mockFileComp = new FileNameCompleter()
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], mockFileComp)
- def candidates = []
- assert 'x = \'/usr/'.length() == completor.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }}
+ candidates << 'foobar'
+ 5
+ }
+ filenameCompleterMocker.use {
+ String buffer = linestart + pathstart
+ int result = runTest(buffer, buffer.length(), new FileNameCompleter())
+
+ assert result == "x = '/usr/".length()
+ assert candidates == ['foobar']
+ }
}
void testInGString() {
idCompletorMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['', '{', 'foo']); candidates << 'foobar'; true}
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- // mock asserting GString is not evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = '"\${foo'
- assert 3 == completor.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }
+
+ int result = runTest('"\${foo')
+
+ assert result == 3
+ assert candidates == ['foobar']
}
void testMultilineComplete() {
@@ -332,16 +253,10 @@ class GroovySyntaxCompletorTest extends CompletorTestSupport {
assert(tokens*.text == ['xyz\nabc', '.', 'subs']); candidates << 'substring('; 7}
bufferManager.buffers.add(['"""xyz'])
bufferManager.setSelected(1)
- IdentifierCompletor mockIdCompletor = idCompletorMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompletor mockReflComp = reflectionCompletorMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompletor completor = new GroovySyntaxCompletor(groovyshMock, mockReflComp, mockIdCompletor, [mockIdCompletor], null)
- def candidates = []
- String buffer = 'abc""".subs'
- assert 7 == completor.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+
+ int result = runTest('abc""".subs')
+
+ assert result == 7
+ assert candidates == ['substring(']
}
}
-