From eecb4fea26aa3d1cddef1bb44ed3500d2b4dd477 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Fri, 4 Oct 2019 14:02:36 +0100 Subject: [PATCH] Use xeval from deno_std (#3058) --- cli/flags.rs | 53 ++++++++++------ cli/lib.rs | 25 -------- cli/ops/os.rs | 1 - cli/tests/043_xeval_delim2.out | 2 - cli/tests/integration_tests.rs | 6 -- js/main.ts | 5 +- js/xeval.ts | 109 --------------------------------- 7 files changed, 36 insertions(+), 165 deletions(-) delete mode 100644 cli/tests/043_xeval_delim2.out delete mode 100644 js/xeval.ts diff --git a/cli/flags.rs b/cli/flags.rs index c8e5c6e31e..24d331bfa2 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -14,7 +14,7 @@ use std::str::FromStr; macro_rules! std_url { ($x:expr) => { - concat!("https://deno.land/std@17a214b/", $x) + concat!("https://deno.land/std@8c90bd9/", $x) }; } @@ -24,6 +24,8 @@ const PRETTIER_URL: &str = std_url!("prettier/main.ts"); const INSTALLER_URL: &str = std_url!("installer/mod.ts"); /// Used for `deno test...` subcommand const TEST_RUNNER_URL: &str = std_url!("testing/runner.ts"); +/// Used for `deno xeval...` subcommand +const XEVAL_URL: &str = std_url!("xeval/mod.ts"); // Creates vector of strings, Vec macro_rules! svec { @@ -54,8 +56,6 @@ pub struct DenoFlags { pub no_fetch: bool, pub seed: Option, pub v8_flags: Option>, - pub xeval_replvar: Option, - pub xeval_delim: Option, // Use tokio::runtime::current_thread pub current_thread: bool, } @@ -705,7 +705,6 @@ pub enum DenoSubcommand { Run, Types, Version, - Xeval, } fn get_default_bundle_filename(source_file: &str) -> String { @@ -899,22 +898,31 @@ pub fn flags_from_vec( _ => unreachable!(), } } - ("xeval", Some(eval_match)) => { + ("xeval", Some(xeval_match)) => { flags.allow_net = true; flags.allow_env = true; flags.allow_run = true; flags.allow_read = true; flags.allow_write = true; flags.allow_hrtime = true; - let code: &str = eval_match.value_of("code").unwrap(); - flags.xeval_replvar = - Some(eval_match.value_of("replvar").unwrap_or("$").to_owned()); - // Currently clap never escapes string, - // So -d "\n" won't expand to newline. - // Instead, do -d $'\n' - flags.xeval_delim = eval_match.value_of("delim").map(String::from); - argv.extend(vec![code.to_string()]); - DenoSubcommand::Xeval + argv.push(XEVAL_URL.to_string()); + + if xeval_match.is_present("delim") { + let delim = xeval_match.value_of("delim").unwrap(); + argv.push("--delim".to_string()); + argv.push(delim.to_string()); + } + + if xeval_match.is_present("replvar") { + let replvar = xeval_match.value_of("replvar").unwrap(); + argv.push("--replvar".to_string()); + argv.push(replvar.to_string()); + } + + let code: &str = xeval_match.value_of("code").unwrap(); + argv.push(code.to_string()); + + DenoSubcommand::Run } (script, Some(script_match)) => { argv.extend(vec![script.to_string()]); @@ -1291,13 +1299,22 @@ mod tests { allow_read: true, allow_write: true, allow_hrtime: true, - xeval_replvar: Some("val".to_owned()), - xeval_delim: Some(" ".to_owned()), ..DenoFlags::default() } ); - assert_eq!(subcommand, DenoSubcommand::Xeval); - assert_eq!(argv, svec!["deno", "console.log(val)"]); + assert_eq!(subcommand, DenoSubcommand::Run); + assert_eq!( + argv, + svec![ + "deno", + XEVAL_URL, + "--delim", + " ", + "--replvar", + "val", + "console.log(val)" + ] + ); } #[test] diff --git a/cli/lib.rs b/cli/lib.rs index 09134dcdb3..6584c0fa3d 100644 --- a/cli/lib.rs +++ b/cli/lib.rs @@ -297,30 +297,6 @@ fn eval_command(flags: DenoFlags, argv: Vec) { tokio_util::run(main_future); } -fn xeval_command(flags: DenoFlags, argv: Vec) { - let xeval_replvar = flags.xeval_replvar.clone().unwrap(); - let (mut worker, state) = create_worker_and_state(flags, argv); - let xeval_source = format!( - "window._xevalWrapper = async function ({}){{ - {} - }}", - &xeval_replvar, &state.argv[1] - ); - - let main_future = lazy(move || { - // Setup runtime. - js_check(worker.execute(&xeval_source)); - js_check(worker.execute("denoMain()")); - worker - .then(|result| { - js_check(result); - Ok(()) - }) - .map_err(print_err_and_exit) - }); - tokio_util::run(main_future); -} - fn bundle_command(flags: DenoFlags, argv: Vec) { let (mut _worker, state) = create_worker_and_state(flags, argv); @@ -429,6 +405,5 @@ pub fn main() { DenoSubcommand::Run => run_script(flags, argv), DenoSubcommand::Types => types_command(), DenoSubcommand::Version => version_command(), - DenoSubcommand::Xeval => xeval_command(flags, argv), } } diff --git a/cli/ops/os.rs b/cli/ops/os.rs index b35b76c2a2..92f640afdc 100644 --- a/cli/ops/os.rs +++ b/cli/ops/os.rs @@ -41,7 +41,6 @@ pub fn op_start( "denoVersion": version::DENO, "tsVersion": version::TYPESCRIPT, "noColor": !colors::use_color(), - "xevalDelim": state.flags.xeval_delim.clone(), "os": BUILD_OS, "arch": BUILD_ARCH, }))) diff --git a/cli/tests/043_xeval_delim2.out b/cli/tests/043_xeval_delim2.out deleted file mode 100644 index 312bdb964a..0000000000 --- a/cli/tests/043_xeval_delim2.out +++ /dev/null @@ -1,2 +0,0 @@ -!MAD -ADAM! diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 930ad9477c..0e30e05c79 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -304,12 +304,6 @@ itest!(_042_dyn_import_evalcontext { output: "042_dyn_import_evalcontext.ts.out", }); -itest!(_043_xeval_delim2 { - args: "xeval -d MADAM console.log($)", - input: Some("!MADMADAMADAM!"), - output: "043_xeval_delim2.out", -}); - itest!(_044_bad_resource { args: "run --reload --allow-read 044_bad_resource.ts", output: "044_bad_resource.ts.out", diff --git a/js/main.ts b/js/main.ts index 6a75f55e03..09e7ce4533 100644 --- a/js/main.ts +++ b/js/main.ts @@ -6,7 +6,6 @@ import * as os from "./os.ts"; import { args } from "./deno.ts"; import { setPrepareStackTrace } from "./error_stack.ts"; import { replLoop } from "./repl.ts"; -import { xevalMain, XevalFunc } from "./xeval.ts"; import { setVersions } from "./version.ts"; import { window } from "./window.ts"; import { setLocation } from "./location.ts"; @@ -35,9 +34,7 @@ function denoMain(preserveDenoNamespace = true, name?: string): void { log("args", args); Object.freeze(args); - if (window["_xevalWrapper"] !== undefined) { - xevalMain(window["_xevalWrapper"] as XevalFunc, s.xevalDelim); - } else if (!s.mainModule) { + if (!s.mainModule) { replLoop(); } } diff --git a/js/xeval.ts b/js/xeval.ts deleted file mode 100644 index 29adcbcafc..0000000000 --- a/js/xeval.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Buffer, writeAll } from "./buffer.ts"; -import { stdin } from "./files.ts"; -import { TextEncoder, TextDecoder } from "./text_encoding.ts"; -import { Reader, EOF } from "./io.ts"; - -export type XevalFunc = (v: string) => void; - -// Generate longest proper prefix which is also suffix array. -function createLPS(pat: Uint8Array): Uint8Array { - const lps = new Uint8Array(pat.length); - lps[0] = 0; - let prefixEnd = 0; - let i = 1; - while (i < lps.length) { - if (pat[i] == pat[prefixEnd]) { - prefixEnd++; - lps[i] = prefixEnd; - i++; - } else if (prefixEnd === 0) { - lps[i] = 0; - i++; - } else { - prefixEnd = pat[prefixEnd - 1]; - } - } - return lps; -} - -// TODO(kevinkassimo): Move this utility to deno_std. -// Import from there once doable. -// Read from reader until EOF and emit string chunks separated -// by the given delimiter. -async function* chunks( - reader: Reader, - delim: string -): AsyncIterableIterator { - const encoder = new TextEncoder(); - const decoder = new TextDecoder(); - // Avoid unicode problems - const delimArr = encoder.encode(delim); - const delimLen = delimArr.length; - const delimLPS = createLPS(delimArr); - - let inputBuffer = new Buffer(); - const inspectArr = new Uint8Array(Math.max(1024, delimLen + 1)); - - // Modified KMP - let inspectIndex = 0; - let matchIndex = 0; - while (true) { - const result = await reader.read(inspectArr); - if (result === EOF) { - // Yield last chunk. - const lastChunk = inputBuffer.toString(); - yield lastChunk; - return; - } - if ((result as number) < 0) { - // Discard all remaining and silently fail. - return; - } - const sliceRead = inspectArr.subarray(0, result as number); - await writeAll(inputBuffer, sliceRead); - - let sliceToProcess = inputBuffer.bytes(); - while (inspectIndex < sliceToProcess.length) { - if (sliceToProcess[inspectIndex] === delimArr[matchIndex]) { - inspectIndex++; - matchIndex++; - if (matchIndex === delimLen) { - // Full match - const matchEnd = inspectIndex - delimLen; - const readyBytes = sliceToProcess.subarray(0, matchEnd); - // Copy - const pendingBytes = sliceToProcess.slice(inspectIndex); - const readyChunk = decoder.decode(readyBytes); - yield readyChunk; - // Reset match, different from KMP. - sliceToProcess = pendingBytes; - inspectIndex = 0; - matchIndex = 0; - } - } else { - if (matchIndex === 0) { - inspectIndex++; - } else { - matchIndex = delimLPS[matchIndex - 1]; - } - } - } - // Keep inspectIndex and matchIndex. - inputBuffer = new Buffer(sliceToProcess); - } -} - -export async function xevalMain( - xevalFunc: XevalFunc, - delim_: string | null -): Promise { - if (!delim_) { - delim_ = "\n"; - } - for await (const chunk of chunks(stdin, delim_)) { - // Ignore empty chunks. - if (chunk.length > 0) { - xevalFunc(chunk); - } - } -}