summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2020-05-29 20:24:06 +1000
committerGitHub <noreply@github.com>2020-05-29 12:24:06 +0200
commit2668637e9bad75bef016e7f8a5f481b3c6221891 (patch)
tree5c3d2801e7de03e14f6896db402941dc3f2846d2
parent958f21e7abc36f0a5abaa381ed8d7f94c723f3fb (diff)
fix: REPL evaluates in strict mode (#5565)
Since everything that Deno loads is treated as an ES Module, it means that all code is treated as "use strict" except for when using the REPL. This PR changes that so code in the REPL is also always evaluated with "use strict". There are also a couple other places where we load code as scripts which should also use "use strict" just in case.
-rw-r--r--cli/js/repl.ts13
-rw-r--r--cli/tests/integration_tests.rs18
-rw-r--r--deno_typescript/compiler_main.js2
-rw-r--r--deno_typescript/system_loader.js2
4 files changed, 32 insertions, 3 deletions
diff --git a/cli/js/repl.ts b/cli/js/repl.ts
index 79273ed33..f38324d11 100644
--- a/cli/js/repl.ts
+++ b/cli/js/repl.ts
@@ -49,11 +49,18 @@ let lastThrownError: Value = undefined;
// Returns true if code is consumed (no error/irrecoverable error).
// Returns false if error is recoverable
function evaluate(code: string): boolean {
- const [result, errInfo] = core.evalContext(code);
+ // each evalContext is a separate function body, and we want strict mode to
+ // work, so we should ensure that the code starts with "use strict"
+ const [result, errInfo] = core.evalContext(`"use strict";\n\n${code}`);
if (!errInfo) {
- lastEvalResult = result;
+ // when a function is eval'ed with just "use strict" sometimes the result
+ // is "use strict" which should be discarded
+ lastEvalResult =
+ typeof result === "string" && result === "use strict"
+ ? undefined
+ : result;
if (!isCloseCalled()) {
- replLog(result);
+ replLog(lastEvalResult);
}
} else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) {
// Recoverable compiler error
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 606a40516..f892b9a87 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -693,6 +693,24 @@ fn repl_test_eof() {
assert!(err.is_empty());
}
+#[test]
+fn repl_test_strict() {
+ let (_, err) = util::run_and_collect_output(
+ true,
+ "repl",
+ Some(vec![
+ "let a = {};",
+ "Object.preventExtensions(a);",
+ "a.c = 1;",
+ ]),
+ None,
+ false,
+ );
+ assert!(err.contains(
+ "Uncaught TypeError: Cannot add property c, object is not extensible"
+ ));
+}
+
const REPL_MSG: &str = "exit using ctrl+d or close()\n";
#[test]
diff --git a/deno_typescript/compiler_main.js b/deno_typescript/compiler_main.js
index 31f539a27..847f3435f 100644
--- a/deno_typescript/compiler_main.js
+++ b/deno_typescript/compiler_main.js
@@ -5,6 +5,8 @@
// understood by the TypeScript language service, so it allows type safety
// checking in VSCode.
+"use strict";
+
const ASSETS = "$asset$";
/**
diff --git a/deno_typescript/system_loader.js b/deno_typescript/system_loader.js
index 0004d055d..fdf1fa872 100644
--- a/deno_typescript/system_loader.js
+++ b/deno_typescript/system_loader.js
@@ -2,6 +2,8 @@
// This is a specialised implementation of a System module loader.
+"use strict";
+
// @ts-nocheck
/* eslint-disable */
let System, __instantiateAsync, __instantiate;