1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 08:09:08 -05:00

Use xeval from deno_std (#3058)

This commit is contained in:
Nayeem Rahman 2019-10-04 14:02:36 +01:00 committed by Ryan Dahl
parent 403bdfc3ec
commit eecb4fea26
7 changed files with 36 additions and 165 deletions

View file

@ -14,7 +14,7 @@ use std::str::FromStr;
macro_rules! std_url { macro_rules! std_url {
($x:expr) => { ($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"); const INSTALLER_URL: &str = std_url!("installer/mod.ts");
/// Used for `deno test...` subcommand /// Used for `deno test...` subcommand
const TEST_RUNNER_URL: &str = std_url!("testing/runner.ts"); 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<String> // Creates vector of strings, Vec<String>
macro_rules! svec { macro_rules! svec {
@ -54,8 +56,6 @@ pub struct DenoFlags {
pub no_fetch: bool, pub no_fetch: bool,
pub seed: Option<u64>, pub seed: Option<u64>,
pub v8_flags: Option<Vec<String>>, pub v8_flags: Option<Vec<String>>,
pub xeval_replvar: Option<String>,
pub xeval_delim: Option<String>,
// Use tokio::runtime::current_thread // Use tokio::runtime::current_thread
pub current_thread: bool, pub current_thread: bool,
} }
@ -705,7 +705,6 @@ pub enum DenoSubcommand {
Run, Run,
Types, Types,
Version, Version,
Xeval,
} }
fn get_default_bundle_filename(source_file: &str) -> String { fn get_default_bundle_filename(source_file: &str) -> String {
@ -899,22 +898,31 @@ pub fn flags_from_vec(
_ => unreachable!(), _ => unreachable!(),
} }
} }
("xeval", Some(eval_match)) => { ("xeval", Some(xeval_match)) => {
flags.allow_net = true; flags.allow_net = true;
flags.allow_env = true; flags.allow_env = true;
flags.allow_run = true; flags.allow_run = true;
flags.allow_read = true; flags.allow_read = true;
flags.allow_write = true; flags.allow_write = true;
flags.allow_hrtime = true; flags.allow_hrtime = true;
let code: &str = eval_match.value_of("code").unwrap(); argv.push(XEVAL_URL.to_string());
flags.xeval_replvar =
Some(eval_match.value_of("replvar").unwrap_or("$").to_owned()); if xeval_match.is_present("delim") {
// Currently clap never escapes string, let delim = xeval_match.value_of("delim").unwrap();
// So -d "\n" won't expand to newline. argv.push("--delim".to_string());
// Instead, do -d $'\n' argv.push(delim.to_string());
flags.xeval_delim = eval_match.value_of("delim").map(String::from); }
argv.extend(vec![code.to_string()]);
DenoSubcommand::Xeval 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)) => { (script, Some(script_match)) => {
argv.extend(vec![script.to_string()]); argv.extend(vec![script.to_string()]);
@ -1291,13 +1299,22 @@ mod tests {
allow_read: true, allow_read: true,
allow_write: true, allow_write: true,
allow_hrtime: true, allow_hrtime: true,
xeval_replvar: Some("val".to_owned()),
xeval_delim: Some(" ".to_owned()),
..DenoFlags::default() ..DenoFlags::default()
} }
); );
assert_eq!(subcommand, DenoSubcommand::Xeval); assert_eq!(subcommand, DenoSubcommand::Run);
assert_eq!(argv, svec!["deno", "console.log(val)"]); assert_eq!(
argv,
svec![
"deno",
XEVAL_URL,
"--delim",
" ",
"--replvar",
"val",
"console.log(val)"
]
);
} }
#[test] #[test]

View file

@ -297,30 +297,6 @@ fn eval_command(flags: DenoFlags, argv: Vec<String>) {
tokio_util::run(main_future); tokio_util::run(main_future);
} }
fn xeval_command(flags: DenoFlags, argv: Vec<String>) {
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<String>) { fn bundle_command(flags: DenoFlags, argv: Vec<String>) {
let (mut _worker, state) = create_worker_and_state(flags, argv); let (mut _worker, state) = create_worker_and_state(flags, argv);
@ -429,6 +405,5 @@ pub fn main() {
DenoSubcommand::Run => run_script(flags, argv), DenoSubcommand::Run => run_script(flags, argv),
DenoSubcommand::Types => types_command(), DenoSubcommand::Types => types_command(),
DenoSubcommand::Version => version_command(), DenoSubcommand::Version => version_command(),
DenoSubcommand::Xeval => xeval_command(flags, argv),
} }
} }

View file

@ -41,7 +41,6 @@ pub fn op_start(
"denoVersion": version::DENO, "denoVersion": version::DENO,
"tsVersion": version::TYPESCRIPT, "tsVersion": version::TYPESCRIPT,
"noColor": !colors::use_color(), "noColor": !colors::use_color(),
"xevalDelim": state.flags.xeval_delim.clone(),
"os": BUILD_OS, "os": BUILD_OS,
"arch": BUILD_ARCH, "arch": BUILD_ARCH,
}))) })))

View file

@ -1,2 +0,0 @@
!MAD
ADAM!

View file

@ -304,12 +304,6 @@ itest!(_042_dyn_import_evalcontext {
output: "042_dyn_import_evalcontext.ts.out", 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 { itest!(_044_bad_resource {
args: "run --reload --allow-read 044_bad_resource.ts", args: "run --reload --allow-read 044_bad_resource.ts",
output: "044_bad_resource.ts.out", output: "044_bad_resource.ts.out",

View file

@ -6,7 +6,6 @@ import * as os from "./os.ts";
import { args } from "./deno.ts"; import { args } from "./deno.ts";
import { setPrepareStackTrace } from "./error_stack.ts"; import { setPrepareStackTrace } from "./error_stack.ts";
import { replLoop } from "./repl.ts"; import { replLoop } from "./repl.ts";
import { xevalMain, XevalFunc } from "./xeval.ts";
import { setVersions } from "./version.ts"; import { setVersions } from "./version.ts";
import { window } from "./window.ts"; import { window } from "./window.ts";
import { setLocation } from "./location.ts"; import { setLocation } from "./location.ts";
@ -35,9 +34,7 @@ function denoMain(preserveDenoNamespace = true, name?: string): void {
log("args", args); log("args", args);
Object.freeze(args); Object.freeze(args);
if (window["_xevalWrapper"] !== undefined) { if (!s.mainModule) {
xevalMain(window["_xevalWrapper"] as XevalFunc, s.xevalDelim);
} else if (!s.mainModule) {
replLoop(); replLoop();
} }
} }

View file

@ -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<string> {
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<void> {
if (!delim_) {
delim_ = "\n";
}
for await (const chunk of chunks(stdin, delim_)) {
// Ignore empty chunks.
if (chunk.length > 0) {
xevalFunc(chunk);
}
}
}