mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 23:59:59 -05:00
Use xeval from deno_std (#3058)
This commit is contained in:
parent
403bdfc3ec
commit
eecb4fea26
7 changed files with 36 additions and 165 deletions
53
cli/flags.rs
53
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<String>
|
||||
macro_rules! svec {
|
||||
|
@ -54,8 +56,6 @@ pub struct DenoFlags {
|
|||
pub no_fetch: bool,
|
||||
pub seed: Option<u64>,
|
||||
pub v8_flags: Option<Vec<String>>,
|
||||
pub xeval_replvar: Option<String>,
|
||||
pub xeval_delim: Option<String>,
|
||||
// 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]
|
||||
|
|
25
cli/lib.rs
25
cli/lib.rs
|
@ -297,30 +297,6 @@ fn eval_command(flags: DenoFlags, argv: Vec<String>) {
|
|||
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>) {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
})))
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
!MAD
|
||||
ADAM!
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
109
js/xeval.ts
109
js/xeval.ts
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue