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

Support TypeScript eval through deno eval -T flag (#4141)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2020-02-28 06:17:56 -08:00 committed by GitHub
parent b5bf28e68f
commit 7255cc9bc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 5 deletions

View file

@ -132,6 +132,19 @@ impl SourceFileFetcher {
.ok()
}
/// Save a given source file into cache.
/// Allows injection of files that normally would not present
/// in filesystem.
/// This is useful when e.g. TS compiler retrieves a custom file
/// under a dummy specifier.
pub fn save_source_file_in_cache(
&self,
specifier: &ModuleSpecifier,
file: SourceFile,
) {
self.source_file_cache.set(specifier.to_string(), file);
}
pub async fn fetch_source_file(
&self,
specifier: &ModuleSpecifier,

View file

@ -33,6 +33,7 @@ pub enum DenoSubcommand {
},
Eval {
code: String,
as_typescript: bool,
},
Fetch {
files: Vec<String>,
@ -401,7 +402,11 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.allow_plugin = true;
flags.allow_hrtime = true;
let code = matches.value_of("code").unwrap().to_string();
flags.subcommand = DenoSubcommand::Eval { code }
let as_typescript = matches.is_present("ts");
flags.subcommand = DenoSubcommand::Eval {
code,
as_typescript,
}
}
fn info_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
@ -662,7 +667,20 @@ fn eval_subcommand<'a, 'b>() -> App<'a, 'b> {
This command has implicit access to all permissions (--allow-all)
deno eval \"console.log('hello world')\"",
deno eval \"console.log('hello world')\"
To evaluate as TypeScript:
deno eval -T \"const v: string = 'hello'; console.log(v)\"
",
)
.arg(
Arg::with_name("ts")
.long("ts")
.short("T")
.help("Treat eval input as TypeScript")
.takes_value(false)
.multiple(false),
)
.arg(Arg::with_name("code").takes_value(true).required(true))
.arg(v8_flags_arg())
@ -1497,6 +1515,34 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Eval {
code: "'console.log(\"hello\")'".to_string(),
as_typescript: false,
},
allow_net: true,
allow_env: true,
allow_run: true,
allow_read: true,
allow_write: true,
allow_plugin: true,
allow_hrtime: true,
..Flags::default()
}
);
}
#[test]
fn eval_typescript() {
let r = flags_from_vec_safe(svec![
"deno",
"eval",
"-T",
"'console.log(\"hello\")'"
]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Eval {
code: "'console.log(\"hello\")'".to_string(),
as_typescript: true,
},
allow_net: true,
allow_env: true,
@ -1519,6 +1565,7 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Eval {
code: "42".to_string(),
as_typescript: false,
},
v8_flags: Some(svec!["--help"]),
allow_net: true,
@ -2131,6 +2178,7 @@ fn eval_with_cafile() {
Flags {
subcommand: DenoSubcommand::Eval {
code: "console.log('hello world')".to_string(),
as_typescript: false,
},
ca_file: Some("example.crt".to_owned()),
allow_net: true,

View file

@ -57,8 +57,10 @@ mod web_worker;
pub mod worker;
use crate::compilers::TargetLib;
use crate::file_fetcher::SourceFile;
use crate::fs as deno_fs;
use crate::global_state::GlobalState;
use crate::msg::MediaType;
use crate::ops::io::get_stdio;
use crate::state::State;
use crate::worker::MainWorker;
@ -279,14 +281,39 @@ async fn fetch_command(flags: Flags, files: Vec<String>) -> Result<(), ErrBox> {
Ok(())
}
async fn eval_command(flags: Flags, code: String) -> Result<(), ErrBox> {
async fn eval_command(
flags: Flags,
code: String,
as_typescript: bool,
) -> Result<(), ErrBox> {
// Force TypeScript compile.
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$eval.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker = create_main_worker(global_state, main_module.clone())?;
let main_module_url = main_module.as_url().to_owned();
// Create a dummy source file.
let source_file = SourceFile {
filename: main_module_url.to_file_path().unwrap(),
url: main_module_url,
types_url: None,
media_type: if as_typescript {
MediaType::TypeScript
} else {
MediaType::JavaScript
},
source_code: code.clone().into_bytes(),
};
// Save our fake file into file fetcher cache
// to allow module access by TS compiler (e.g. op_fetch_source_files)
worker
.state
.borrow()
.global_state
.file_fetcher
.save_source_file_in_cache(&main_module, source_file);
debug!("main_module {}", &main_module);
worker.execute_module_from_code(&main_module, code).await?;
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
(&mut *worker).await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
@ -409,7 +436,10 @@ pub fn main() {
source_file,
out_file,
} => bundle_command(flags, source_file, out_file).boxed_local(),
DenoSubcommand::Eval { code } => eval_command(flags, code).boxed_local(),
DenoSubcommand::Eval {
code,
as_typescript,
} => eval_command(flags, code, as_typescript).boxed_local(),
DenoSubcommand::Fetch { files } => {
fetch_command(flags, files).boxed_local()
}

View file

@ -0,0 +1 @@
123

View file

@ -788,6 +788,12 @@ itest!(_029_eval {
output: "029_eval.out",
});
// Ugly parentheses due to whitespace delimiting problem.
itest!(_030_eval_ts {
args: "eval -T console.log((123)as(number))", // 'as' is a TS keyword only
output: "030_eval_ts.out",
});
itest!(_033_import_map {
args:
"run --reload --importmap=importmaps/import_map.json importmaps/test.ts",