Skip to content

Commit

Permalink
Change default version to VERSION_ECMASCRIPT
Browse files Browse the repository at this point in the history
This changes the version set when a Context object is created to
VERSION_ECMASCRIPT by default. This version is equivalent to 
VERSION_ES6, which many people have been using in newer apps.
  • Loading branch information
gbrail authored Dec 17, 2024
1 parent 8f8c3dc commit ba55268
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class RhinoScriptEngine extends AbstractScriptEngine implements Compilabl
*/
public static final String INTERPRETED_MODE = "org.mozilla.javascript.interpreted_mode";

static final int DEFAULT_LANGUAGE_VERSION = Context.VERSION_ES6;
static final int DEFAULT_LANGUAGE_VERSION = Context.VERSION_ECMASCRIPT;
private static final boolean DEFAULT_DEBUG = true;
private static final String DEFAULT_FILENAME = "eval";

Expand Down Expand Up @@ -349,7 +349,7 @@ protected boolean hasFeature(Context cx, int featureIndex) {

@Override
protected void onContextCreated(Context cx) {
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setLanguageVersion(Context.VERSION_ECMASCRIPT);
cx.setGeneratingDebug(DEFAULT_DEBUG);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static void main(String[] args) {

main.attachTo(org.mozilla.javascript.tools.shell.Main.shellContextFactory);
try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setLanguageVersion(Context.VERSION_ECMASCRIPT);

Global global = org.mozilla.javascript.tools.shell.Main.getGlobal();
global.init(cx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public class ShellContextFactory extends ContextFactory {
private boolean strictMode;
private boolean warningAsError;
private int languageVersion = Context.VERSION_ES6;
private int languageVersion = Context.VERSION_ECMASCRIPT;
private boolean interpretedMode;
private boolean generatingDebug;
private boolean allowReservedKeywords = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class CompilerEnvirons {
public CompilerEnvirons() {
errorReporter = DefaultErrorReporter.instance;
languageVersion = Context.VERSION_DEFAULT;
languageVersion = Context.VERSION_ECMASCRIPT;
generateDebugInfo = true;
reservedKeywordAsIdentifier = true;
allowMemberExprAsFunctionName = false;
Expand Down
47 changes: 39 additions & 8 deletions rhino/src/main/java/org/mozilla/javascript/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ public class Context implements Closeable {
* The unknown version.
*
* <p>Be aware, this version will not support many of the newer language features and will not
* change in the future.
* change in the future. In practice, for historical reasons, this is an odd version that
* doesn't necessarily match any particular version of JavaScript and should not be used.
*
* <p>Please use one of the other constants like VERSION_ES6 to get support for recent language
* features.
* <p>Please use one of the other constants like {@link #VERSION_ECMASCRIPT} to get support for
* recent language features.
*/
public static final int VERSION_UNKNOWN = -1;

Expand Down Expand Up @@ -103,9 +104,23 @@ public class Context implements Closeable {
/** JavaScript 1.8 */
public static final int VERSION_1_8 = 180;

/** ECMAScript 6. */
/**
* Old constant for ECMAScript 6 and after. This has been replaced with the more clearly-named
* {@link #VERSION_ECMASCRIPT}. Both constants have the same value, and this is retained for
* compatibility.
*/
public static final int VERSION_ES6 = 200;

/**
* ECMAScript 6 and after. Since around version 1.7, this has been used to denote most new
* language features. This has the same value as {@link #VERSION_ES6}.
*
* <p>As of version 1.8, the Rhino community has no plans to continue adding new language
* versions, but instead plans to track the ECMAScript specification as it evolves and add new
* features in new versions of Rhino.
*/
public static final int VERSION_ECMASCRIPT = VERSION_ES6;

/**
* Controls behaviour of <code>Date.prototype.getYear()</code>. If <code>
* hasFeature(FEATURE_NON_ECMA_GET_YEAR)</code> returns true, Date.prototype.getYear subtructs
Expand Down Expand Up @@ -363,7 +378,11 @@ public class Context implements Closeable {

/**
* Creates a new Context. The context will be associated with the {@link
* ContextFactory#getGlobal() global context factory}.
* ContextFactory#getGlobal() global context factory}. By default, the new context will run in
* compiled mode and use the {@link #VERSION_ECMASCRIPT} language version, which supports
* features as defined in the most recent ECMAScript standard. This default behavior can be
* changed by overriding the ContextFactory class and installing the new implementation as the
* global ContextFactory.
*
* <p>Note that the Context must be associated with a thread before it can be used to execute a
* script.
Expand All @@ -380,7 +399,10 @@ public Context() {

/**
* Creates a new context. Provided as a preferred super constructor for subclasses in place of
* the deprecated default public constructor.
* the deprecated default public constructor. By default, the new context will run in compiled
* mode and use the {@link #VERSION_ECMASCRIPT} language version, which supports features as
* defined in the most recent ECMAScript standard. This default behavior can be changed by
* overriding the ContextFactory class
*
* @param factory the context factory associated with this context (most likely, the one that
* created the context). Can not be null. The context features are inherited from the
Expand All @@ -392,7 +414,7 @@ protected Context(ContextFactory factory) {
throw new IllegalArgumentException("factory == null");
}
this.factory = factory;
version = VERSION_DEFAULT;
version = VERSION_ECMASCRIPT;
interpretedMode = codegenClass == null;
maximumInterpreterStackDepth = Integer.MAX_VALUE;
}
Expand Down Expand Up @@ -659,7 +681,16 @@ public final int getLanguageVersion() {
* Set the language version.
*
* <p>Setting the language version will affect functions and scripts compiled subsequently. See
* the overview documentation for version-specific behavior.
* the overview documentation for version-specific behavior. The default version is {@link
* #VERSION_ECMASCRIPT}, which represents the newest ECMAScript features implemented by Rhino,
* and this is the version that should be used unless a project needs backwards compatibility
* with older Rhino scripts that may depend on behaviors from the earlier history of JavaScript.
*
* <p>As of version 1.8, the Rhino community has no plans to continue to add new language
* versions, but instead plans to track the ECMAScript standard and add new features as the
* language evolves in new versions of Rhino, like other JavaScript engines. Projects that use
* Rhino are encouraged to migrate to the {@link #VERSION_ECMASCRIPT} version and stop relying
* on older behaviors of Rhino that are no longer compatible with ECMAScript.
*
* @param version the version as specified by VERSION_1_0, VERSION_1_1, etc.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public void sameValueDifferentTopology() {
@Test
public void heterogenousScriptables() {
try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
ScriptableObject top = cx.initStandardObjects();
ScriptRuntime.doTopCall(
(Callable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private interface Action {

private static ContextAction<Void> action(final String fn, final Action a) {
return cx -> {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
ScriptableObject scope1 = cx.initStandardObjects();
ScriptableObject scope2 = cx.initStandardObjects();
scope1.put("scope2", scope1, scope2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public void test1() throws Exception {

private NativeContinuation createContinuation() throws Exception {
try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
cx.setOptimizationLevel(-1); // interpreter for continuations
ScriptableObject global = cx.initStandardObjects();
final AtomicReference<NativeContinuation> captured = new AtomicReference<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public static Collection<Object[]> singleDoctest() throws IOException {
public void runDoctest() throws Exception {
ContextFactory factory = ContextFactory.getGlobal();
try (Context cx = factory.enterContext()) {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
cx.setInterpretedMode(interpretedMode);
Global global = new Global(cx);
// global.runDoctest throws an exception on any failure
Expand Down
28 changes: 20 additions & 8 deletions tests/src/test/java/org/mozilla/javascript/tests/Evaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,33 @@ public static Object eval(String source) {
return eval(source, null);
}

public static Object eval(Context cx, String source) {
return eval(cx, source, null);
}

public static Object eval(String source, String id, Scriptable object) {
return eval(source, Collections.singletonMap(id, object));
}

public static Object eval(Context cx, String source, String id, Scriptable object) {
return eval(cx, source, Collections.singletonMap(id, object));
}

public static Object eval(String source, Map<String, Scriptable> bindings) {
try (Context cx = ContextFactory.getGlobal().enterContext()) {
Scriptable scope = cx.initStandardObjects();
if (bindings != null) {
for (Map.Entry<String, Scriptable> entry : bindings.entrySet()) {
final Scriptable object = entry.getValue();
object.setParentScope(scope);
scope.put(entry.getKey(), scope, object);
}
return eval(cx, source, bindings);
}
}

public static Object eval(Context cx, String source, Map<String, Scriptable> bindings) {
Scriptable scope = cx.initStandardObjects();
if (bindings != null) {
for (Map.Entry<String, Scriptable> entry : bindings.entrySet()) {
final Scriptable object = entry.getValue();
object.setParentScope(scope);
scope.put(entry.getKey(), scope, object);
}
return cx.evaluateString(scope, source, "source", 1, null);
}
return cx.evaluateString(scope, source, "source", 1, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ private static void assertPrintMsg(String source, String expectedMsg) {
DummyConsolePrinter printer = new DummyConsolePrinter();

try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
Scriptable scope = cx.initStandardObjects();
NativeConsole.init(scope, false, printer);
cx.evaluateString(scope, source, "source", 1, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.Assert.assertThrows;

import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Scriptable;

Expand All @@ -11,6 +12,7 @@ public class NullishCoalescingOpTest {
public void testNullishCoalescingOperatorRequiresES6() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
Scriptable scope = cx.initStandardObjects();
assertThrows(
EvaluatorException.class,
Expand Down Expand Up @@ -77,6 +79,7 @@ public void testNullishCoalescingDoesNotLeakVariables() {
public void testNullishAssignmentRequiresES6() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
Scriptable scope = cx.initStandardObjects();
assertThrows(
EvaluatorException.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.Assert.assertThrows;

import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;
Expand All @@ -12,6 +13,7 @@ public class OptionalChainingOperatorTest {
public void requiresES6() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
Scriptable scope = cx.initStandardObjects();
assertThrows(
EvaluatorException.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public class ParserTest {
@Before
public void setUp() throws Exception {
environment = new CompilerEnvirons();
environment.setLanguageVersion(Context.VERSION_DEFAULT);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public void setUp() throws Exception {
}

ctx = Context.enter();
ctx.setLanguageVersion(Context.VERSION_DEFAULT);
scope1 = ctx.newObject(sharedScope);
scope1.setPrototype(sharedScope);
scope1.setParentScope(null);
Expand Down Expand Up @@ -79,7 +80,7 @@ public void importClassWithImporter() throws Exception {
assertEquals(java.sql.Date.class, o);

o = evaluateString(scope1, "Date"); // JavaScript "Statement" function
assertEquals(IdFunctionObject.class, o.getClass());
assertTrue(o instanceof IdFunctionObject);

o = evaluateString(scope2, "typeof imp1"); // scope 2 has
// no imp1
Expand All @@ -104,7 +105,7 @@ public void importPackageWithImporter() throws Exception {
assertEquals(java.sql.Date.class, o);

o = evaluateString(scope1, "Date"); // JavaScript "Statement" function
assertEquals(IdFunctionObject.class, o.getClass());
assertTrue(o instanceof IdFunctionObject);

o = evaluateString(scope2, "typeof imp1 == 'undefined'"); // scope 2 has
// no imp1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public Object call(

@After
public void tearDown() throws Exception {
cx.setLanguageVersion(Context.VERSION_DEFAULT);
Context.exit();
}

Expand Down Expand Up @@ -106,6 +105,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForApplyJS() {
NativeArray arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(undefined)];");

assertNotEquals(arr.get(0), arr.get(1));
Expand All @@ -117,6 +117,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForApplyJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(null)];");
assertNotEquals(arr.get(0), arr.get(1));
assertNotEquals(arr.get(0), arr.get(2));
Expand All @@ -126,6 +127,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForApplyJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(undefined)];");

assertNotEquals(arr.get(0), arr.get(1));
Expand All @@ -137,6 +139,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForApplyJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(null)];");
assertNotEquals(arr.get(0), arr.get(1));
assertNotEquals(arr.get(0), arr.get(2));
Expand All @@ -149,6 +152,7 @@ public void whenVersionLtEq17ThenPassGlobalThisObjForApplyJS() {
NativeArray arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(undefined)];");

assertEquals(arr.get(0), arr.get(1));
Expand All @@ -158,6 +162,7 @@ public void whenVersionLtEq17ThenPassGlobalThisObjForApplyJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.apply(), F2.apply(null)];");

assertEquals(arr.get(0), arr.get(1));
Expand All @@ -171,6 +176,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForCallJS() {
NativeArray arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(undefined)];");

assertNotEquals(arr.get(0), arr.get(1));
Expand All @@ -182,6 +188,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForCallJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(null)];");
assertNotEquals(arr.get(0), arr.get(1));
assertNotEquals(arr.get(0), arr.get(2));
Expand All @@ -191,6 +198,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForCallJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(undefined)];");

assertNotEquals(arr.get(0), arr.get(1));
Expand All @@ -202,6 +210,7 @@ public void whenVersionGt17ThenPassNullAsThisObjForCallJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(null)];");
assertNotEquals(arr.get(0), arr.get(1));
assertNotEquals(arr.get(0), arr.get(2));
Expand All @@ -214,6 +223,7 @@ public void whenVersionLtEq17ThenPassGlobalThisObjForCallJS() {
NativeArray arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(undefined)];");

assertEquals(arr.get(0), arr.get(1));
Expand All @@ -223,6 +233,7 @@ public void whenVersionLtEq17ThenPassGlobalThisObjForCallJS() {
arr =
(NativeArray)
Evaluator.eval(
cx,
"function F2() {return this;};[this, F2.call(), F2.call(null)];");

assertEquals(arr.get(0), arr.get(1));
Expand Down
Loading

0 comments on commit ba55268

Please sign in to comment.