Skip to content

Commit 1950c73

Browse files
committed
Use Scala 2.12.0-M4's JSR-223 script engine
This updates to Scala version 2.12.0-M4, and adapts its included JSR-223 ScriptEngineFactory, rather than reinventing our own. It relies on a couple of hack workarounds from takawitter: https://gist.github.com/takawitter/5479445
1 parent a34f844 commit 1950c73

File tree

4 files changed

+58
-126
lines changed

4 files changed

+58
-126
lines changed

pom.xml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<parent>
99
<groupId>org.scijava</groupId>
1010
<artifactId>pom-scijava</artifactId>
11-
<version>9.0.0</version>
11+
<version>10.1.0</version>
1212
<relativePath />
1313
</parent>
1414

@@ -87,7 +87,8 @@
8787
</ciManagement>
8888

8989
<properties>
90-
<scala.version>2.10.0</scala.version>
90+
<scijava.jvm.version>1.8</scijava.jvm.version>
91+
<scala.version>2.12.0-M4</scala.version>
9192
</properties>
9293

9394
<dependencies>
@@ -97,12 +98,7 @@
9798
<artifactId>scijava-common</artifactId>
9899
</dependency>
99100

100-
<!-- Third-party dependencies -->
101-
<dependency>
102-
<groupId>org.scala-lang</groupId>
103-
<artifactId>scala-library</artifactId>
104-
<version>${scala.version}</version>
105-
</dependency>
101+
<!-- Scala dependencies -->
106102
<dependency>
107103
<groupId>org.scala-lang</groupId>
108104
<artifactId>scala-compiler</artifactId>

src/main/java/org/scijava/plugins/scripting/scala/ScalaBindings.java

Lines changed: 0 additions & 52 deletions
This file was deleted.

src/main/java/org/scijava/plugins/scripting/scala/ScalaScriptEngine.java

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -30,77 +30,69 @@
3030

3131
package org.scijava.plugins.scripting.scala;
3232

33-
import java.io.BufferedReader;
34-
import java.io.PrintWriter;
35-
import java.io.Reader;
36-
import java.io.StringWriter;
37-
import java.io.Writer;
38-
import java.util.Map.Entry;
33+
import javax.script.ScriptEngine;
3934

40-
import javax.script.ScriptContext;
41-
import javax.script.ScriptException;
35+
import org.scijava.script.AdaptedScriptEngine;
4236

43-
import org.scijava.script.AbstractScriptEngine;
44-
45-
import scala.collection.immutable.List;
46-
import scala.tools.nsc.Settings;
4737
import scala.tools.nsc.interpreter.IMain;
38+
import scala.tools.nsc.settings.MutableSettings.BooleanSetting;
4839

4940
/**
50-
* A Scala interpreter for ImageJ.
51-
*
52-
* @author Johannes Schindelin
41+
* An adapter of the Scala script engine.
42+
*
43+
* @author Curtis Rueden
5344
*/
54-
public class ScalaScriptEngine extends AbstractScriptEngine {
45+
public class ScalaScriptEngine extends AdaptedScriptEngine {
5546

56-
{
57-
engineScopeBindings = new ScalaBindings();
58-
}
47+
private final IMain engine;
5948

60-
@Override
61-
public Object eval(final String script) throws ScriptException {
62-
try {
63-
return interpreter().interpret(script);
64-
}
65-
catch (final Exception e) {
66-
throw new ScriptException(e);
49+
public ScalaScriptEngine(final ScriptEngine engine) {
50+
super(engine);
51+
52+
if (!(engine instanceof IMain)) {
53+
throw new IllegalArgumentException(//
54+
"Not a Scala script engine: " + engine.getClass().getName());
6755
}
56+
this.engine = (IMain) engine;
57+
58+
enableClassPath();
6859
}
6960

61+
// -- ScriptEngine methods --
62+
7063
@Override
71-
public Object eval(final Reader reader) throws ScriptException {
72-
try {
73-
final BufferedReader bufferedReader = new BufferedReader(reader);
74-
final StringWriter writer = new StringWriter();
75-
for (;;) {
76-
final String line = bufferedReader.readLine();
77-
if (line == null) break;
78-
writer.write(line);
79-
writer.write("\n");
80-
}
81-
return interpreter().interpret(writer.toString());
82-
}
83-
catch (final Exception e) {
84-
throw new ScriptException(e);
85-
}
64+
public void put(final String key, final Object value) {
65+
// NB: Add a suffix to the key indicating its type.
66+
// This is necessary in order to properly populate the variable.
67+
//
68+
// Thanks to takawitter for this invocation:
69+
// https://gist.github.com/takawitter/5479445
70+
71+
engine.put(key + ": " + value.getClass().getName(), value);
8672
}
8773

88-
private IMain interpreter() {
89-
final ScriptContext context = getContext();
90-
final Writer writer = context.getWriter();
74+
// -- Helper methods --
9175

92-
final Settings settings = new Settings();
93-
settings.usejavacp().tryToSet(List.make(1, "true"));
94-
final PrintWriter out = writer == null ? null :
95-
(writer instanceof PrintWriter ? (PrintWriter)writer : new PrintWriter(writer));
96-
final IMain interpreter = out == null ? new IMain(settings) : new IMain(settings, out);
76+
private void enableClassPath() {
77+
// NB: Enable class-path-based processing.
78+
//
79+
// Without this, the engine fails with the following error:
80+
//
81+
// [init] error: error while loading Object, Missing dependency
82+
// 'object scala in compiler mirror', required by
83+
// .../lib/rt.jar(java/lang/Object.class)
84+
//
85+
// Failed to initialize compiler: object scala in compiler mirror not found.
86+
// ** Note that as of 2.8 scala does not assume use of the java classpath.
87+
// ** For the old behavior pass -usejavacp to scala, or if using a Settings
88+
// ** object programmatically, settings.usejavacp.value = true.
89+
//
90+
// Thanks to takawitter for this invocation:
91+
// https://gist.github.com/takawitter/5479445
9792

98-
for (final Entry<String, Object> entry : engineScopeBindings.entrySet()) {
99-
final String name = entry.getKey();
100-
final Object value = entry.getValue();
101-
interpreter.bind(name, value.getClass().getCanonicalName(), value, List.make(0, ""));
102-
}
103-
104-
return interpreter;
93+
final BooleanSetting usejavacp = //
94+
(BooleanSetting) engine.settings().usejavacp();
95+
usejavacp.value_$eq(true);
10596
}
97+
10698
}

src/main/java/org/scijava/plugins/scripting/scala/ScalaScriptLanguage.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,28 @@
3030

3131
package org.scijava.plugins.scripting.scala;
3232

33-
import java.util.Arrays;
34-
import java.util.List;
35-
3633
import javax.script.ScriptEngine;
3734

3835
import org.scijava.plugin.Plugin;
39-
import org.scijava.script.AbstractScriptLanguage;
36+
import org.scijava.script.AdaptedScriptLanguage;
4037
import org.scijava.script.ScriptLanguage;
4138

4239
/**
4340
* An adapter of the Scala interpreter to the SciJava scripting interface.
4441
*
42+
* @author Curtis Rueden
4543
* @author Johannes Schindelin
4644
* @see ScriptEngine
4745
*/
4846
@Plugin(type = ScriptLanguage.class, name = "Scala")
49-
public class ScalaScriptLanguage extends AbstractScriptLanguage {
47+
public class ScalaScriptLanguage extends AdaptedScriptLanguage {
5048

51-
@Override
52-
public List<String> getExtensions() {
53-
return Arrays.asList("scala");
49+
public ScalaScriptLanguage() {
50+
super("scala");
5451
}
5552

5653
@Override
5754
public ScriptEngine getScriptEngine() {
58-
return new ScalaScriptEngine();
55+
return new ScalaScriptEngine(super.getScriptEngine());
5956
}
60-
6157
}

0 commit comments

Comments
 (0)