2019-01-09 12:59:46 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2019-03-14 19:17:52 -04:00
|
|
|
use crate::isolate_state::IsolateState;
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::msg;
|
2019-03-18 16:46:23 -04:00
|
|
|
use crate::permissions::{DenoPermissions, PermissionAccessor};
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::resources;
|
|
|
|
use crate::resources::Resource;
|
|
|
|
use crate::resources::ResourceId;
|
2019-03-18 20:03:37 -04:00
|
|
|
use crate::startup_data;
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::workers;
|
2019-03-19 16:47:35 -04:00
|
|
|
use deno_core::Buf;
|
2019-01-09 12:59:46 -05:00
|
|
|
use futures::Future;
|
|
|
|
use serde_json;
|
2019-02-18 10:42:15 -05:00
|
|
|
use std::str;
|
2019-01-09 12:59:46 -05:00
|
|
|
use std::sync::Mutex;
|
|
|
|
|
|
|
|
lazy_static! {
|
2019-01-16 10:27:17 -05:00
|
|
|
static ref C_RID: Mutex<Option<ResourceId>> = Mutex::new(None);
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// This corresponds to JS ModuleMetaData.
|
|
|
|
// TODO Rename one or the other so they correspond.
|
|
|
|
#[derive(Debug)]
|
2019-02-18 10:42:15 -05:00
|
|
|
pub struct ModuleMetaData {
|
2019-01-09 12:59:46 -05:00
|
|
|
pub module_name: String,
|
|
|
|
pub filename: String,
|
|
|
|
pub media_type: msg::MediaType,
|
2019-02-18 10:42:15 -05:00
|
|
|
pub source_code: Vec<u8>,
|
2019-02-02 01:28:31 -05:00
|
|
|
pub maybe_output_code_filename: Option<String>,
|
2019-02-18 10:42:15 -05:00
|
|
|
pub maybe_output_code: Option<Vec<u8>>,
|
2019-02-02 01:28:31 -05:00
|
|
|
pub maybe_source_map_filename: Option<String>,
|
2019-02-18 10:42:15 -05:00
|
|
|
pub maybe_source_map: Option<Vec<u8>>,
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
|
2019-02-18 10:42:15 -05:00
|
|
|
impl ModuleMetaData {
|
2019-01-15 07:06:25 -05:00
|
|
|
pub fn js_source(&self) -> String {
|
2019-01-09 12:59:46 -05:00
|
|
|
if self.media_type == msg::MediaType::Json {
|
2019-02-18 10:42:15 -05:00
|
|
|
return format!(
|
|
|
|
"export default {};",
|
|
|
|
str::from_utf8(&self.source_code).unwrap()
|
|
|
|
);
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
match self.maybe_output_code {
|
2019-02-18 10:42:15 -05:00
|
|
|
None => str::from_utf8(&self.source_code).unwrap().to_string(),
|
|
|
|
Some(ref output_code) => str::from_utf8(output_code).unwrap().to_string(),
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-14 19:17:52 -04:00
|
|
|
fn lazy_start(parent_state: &IsolateState) -> Resource {
|
2019-01-16 10:27:17 -05:00
|
|
|
let mut cell = C_RID.lock().unwrap();
|
2019-03-18 20:03:37 -04:00
|
|
|
let startup_data = startup_data::compiler_isolate_init();
|
2019-03-01 19:25:50 -05:00
|
|
|
let permissions = DenoPermissions {
|
2019-03-18 16:46:23 -04:00
|
|
|
allow_read: PermissionAccessor::from(true),
|
|
|
|
allow_write: PermissionAccessor::from(true),
|
|
|
|
allow_net: PermissionAccessor::from(true),
|
2019-03-13 12:43:47 -04:00
|
|
|
..Default::default()
|
2019-03-01 19:25:50 -05:00
|
|
|
};
|
2019-03-14 19:17:52 -04:00
|
|
|
|
2019-01-09 12:59:46 -05:00
|
|
|
let rid = cell.get_or_insert_with(|| {
|
2019-03-01 19:25:50 -05:00
|
|
|
let resource = workers::spawn(
|
2019-03-18 20:03:37 -04:00
|
|
|
Some(startup_data),
|
2019-03-14 19:17:52 -04:00
|
|
|
parent_state,
|
2019-03-01 19:25:50 -05:00
|
|
|
"compilerMain()".to_string(),
|
|
|
|
permissions,
|
|
|
|
);
|
2019-01-09 12:59:46 -05:00
|
|
|
resource.rid
|
|
|
|
});
|
|
|
|
Resource { rid: *rid }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn req(specifier: &str, referrer: &str) -> Buf {
|
|
|
|
json!({
|
|
|
|
"specifier": specifier,
|
|
|
|
"referrer": referrer,
|
|
|
|
}).to_string()
|
|
|
|
.into_boxed_str()
|
|
|
|
.into_boxed_bytes()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn compile_sync(
|
2019-03-14 19:17:52 -04:00
|
|
|
parent_state: &IsolateState,
|
2019-01-09 12:59:46 -05:00
|
|
|
specifier: &str,
|
|
|
|
referrer: &str,
|
2019-02-18 10:42:15 -05:00
|
|
|
module_meta_data: &ModuleMetaData,
|
|
|
|
) -> ModuleMetaData {
|
2019-01-09 12:59:46 -05:00
|
|
|
let req_msg = req(specifier, referrer);
|
|
|
|
|
|
|
|
let compiler = lazy_start(parent_state);
|
|
|
|
|
|
|
|
let send_future = resources::worker_post_message(compiler.rid, req_msg);
|
|
|
|
send_future.wait().unwrap();
|
|
|
|
|
|
|
|
let recv_future = resources::worker_recv_message(compiler.rid);
|
2019-03-14 19:17:52 -04:00
|
|
|
let result = recv_future.wait().unwrap();
|
|
|
|
assert!(result.is_some());
|
|
|
|
let res_msg = result.unwrap();
|
2019-01-09 12:59:46 -05:00
|
|
|
|
|
|
|
let res_json = std::str::from_utf8(&res_msg).unwrap();
|
2019-02-18 10:42:15 -05:00
|
|
|
match serde_json::from_str::<serde_json::Value>(res_json) {
|
|
|
|
Ok(serde_json::Value::Object(map)) => ModuleMetaData {
|
|
|
|
module_name: module_meta_data.module_name.clone(),
|
|
|
|
filename: module_meta_data.filename.clone(),
|
|
|
|
media_type: module_meta_data.media_type,
|
|
|
|
source_code: module_meta_data.source_code.clone(),
|
|
|
|
maybe_output_code: match map["outputCode"].as_str() {
|
|
|
|
Some(str) => Some(str.as_bytes().to_owned()),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
maybe_output_code_filename: None,
|
|
|
|
maybe_source_map: match map["sourceMap"].as_str() {
|
|
|
|
Some(str) => Some(str.as_bytes().to_owned()),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
maybe_source_map_filename: None,
|
|
|
|
},
|
|
|
|
_ => panic!("error decoding compiler response"),
|
|
|
|
}
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_compile_sync() {
|
|
|
|
let cwd = std::env::current_dir().unwrap();
|
|
|
|
let cwd_string = cwd.to_str().unwrap().to_owned();
|
|
|
|
|
|
|
|
let specifier = "./tests/002_hello.ts";
|
|
|
|
let referrer = cwd_string + "/";
|
|
|
|
|
2019-02-18 10:42:15 -05:00
|
|
|
let mut out = ModuleMetaData {
|
|
|
|
module_name: "xxx".to_owned(),
|
|
|
|
filename: "/tests/002_hello.ts".to_owned(),
|
|
|
|
media_type: msg::MediaType::TypeScript,
|
|
|
|
source_code: "console.log(\"Hello World\");".as_bytes().to_owned(),
|
|
|
|
maybe_output_code_filename: None,
|
|
|
|
maybe_output_code: None,
|
|
|
|
maybe_source_map_filename: None,
|
|
|
|
maybe_source_map: None,
|
|
|
|
};
|
|
|
|
|
|
|
|
out = compile_sync(&IsolateState::mock(), specifier, &referrer, &mut out);
|
|
|
|
assert!(
|
|
|
|
out
|
|
|
|
.maybe_output_code
|
|
|
|
.unwrap()
|
|
|
|
.starts_with("console.log(\"Hello World\");".as_bytes())
|
|
|
|
);
|
2019-01-09 12:59:46 -05:00
|
|
|
}
|
|
|
|
}
|