mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
This reverts commit 174e496847
.
That commit caused panic on startup like
https://github.com/denoland/deno/issues/28047
or https://github.com/denoland/deno/issues/28044.
Reverting for now, until we figure out what's going wrong.
This commit is contained in:
parent
0945634127
commit
acdc7dcdcf
8 changed files with 580 additions and 599 deletions
485
cli/build.rs
485
cli/build.rs
|
@ -1,183 +1,318 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
use std::path::PathBuf;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
|
use deno_core::snapshot::*;
|
||||||
use deno_runtime::*;
|
use deno_runtime::*;
|
||||||
|
|
||||||
fn compress_decls(out_dir: &Path) {
|
mod ts {
|
||||||
let decls = [
|
use std::collections::HashMap;
|
||||||
"lib.deno_webgpu.d.ts",
|
use std::io::Write;
|
||||||
"lib.deno.ns.d.ts",
|
use std::path::Path;
|
||||||
"lib.deno.unstable.d.ts",
|
use std::path::PathBuf;
|
||||||
"lib.deno.window.d.ts",
|
|
||||||
"lib.deno.worker.d.ts",
|
use deno_core::op2;
|
||||||
"lib.deno.shared_globals.d.ts",
|
use deno_core::v8;
|
||||||
"lib.deno.ns.d.ts",
|
use deno_core::OpState;
|
||||||
"lib.deno.unstable.d.ts",
|
use deno_error::JsErrorBox;
|
||||||
"lib.decorators.d.ts",
|
use serde::Serialize;
|
||||||
"lib.decorators.legacy.d.ts",
|
|
||||||
"lib.dom.asynciterable.d.ts",
|
use super::*;
|
||||||
"lib.dom.d.ts",
|
|
||||||
"lib.dom.extras.d.ts",
|
#[derive(Debug, Serialize)]
|
||||||
"lib.dom.iterable.d.ts",
|
#[serde(rename_all = "camelCase")]
|
||||||
"lib.es2015.collection.d.ts",
|
struct LoadResponse {
|
||||||
"lib.es2015.core.d.ts",
|
data: String,
|
||||||
"lib.es2015.d.ts",
|
version: String,
|
||||||
"lib.es2015.generator.d.ts",
|
script_kind: i32,
|
||||||
"lib.es2015.iterable.d.ts",
|
|
||||||
"lib.es2015.promise.d.ts",
|
|
||||||
"lib.es2015.proxy.d.ts",
|
|
||||||
"lib.es2015.reflect.d.ts",
|
|
||||||
"lib.es2015.symbol.d.ts",
|
|
||||||
"lib.es2015.symbol.wellknown.d.ts",
|
|
||||||
"lib.es2016.array.include.d.ts",
|
|
||||||
"lib.es2016.d.ts",
|
|
||||||
"lib.es2016.full.d.ts",
|
|
||||||
"lib.es2016.intl.d.ts",
|
|
||||||
"lib.es2017.arraybuffer.d.ts",
|
|
||||||
"lib.es2017.d.ts",
|
|
||||||
"lib.es2017.date.d.ts",
|
|
||||||
"lib.es2017.full.d.ts",
|
|
||||||
"lib.es2017.intl.d.ts",
|
|
||||||
"lib.es2017.object.d.ts",
|
|
||||||
"lib.es2017.sharedmemory.d.ts",
|
|
||||||
"lib.es2017.string.d.ts",
|
|
||||||
"lib.es2017.typedarrays.d.ts",
|
|
||||||
"lib.es2018.asyncgenerator.d.ts",
|
|
||||||
"lib.es2018.asynciterable.d.ts",
|
|
||||||
"lib.es2018.d.ts",
|
|
||||||
"lib.es2018.full.d.ts",
|
|
||||||
"lib.es2018.intl.d.ts",
|
|
||||||
"lib.es2018.promise.d.ts",
|
|
||||||
"lib.es2018.regexp.d.ts",
|
|
||||||
"lib.es2019.array.d.ts",
|
|
||||||
"lib.es2019.d.ts",
|
|
||||||
"lib.es2019.full.d.ts",
|
|
||||||
"lib.es2019.intl.d.ts",
|
|
||||||
"lib.es2019.object.d.ts",
|
|
||||||
"lib.es2019.string.d.ts",
|
|
||||||
"lib.es2019.symbol.d.ts",
|
|
||||||
"lib.es2020.bigint.d.ts",
|
|
||||||
"lib.es2020.d.ts",
|
|
||||||
"lib.es2020.date.d.ts",
|
|
||||||
"lib.es2020.full.d.ts",
|
|
||||||
"lib.es2020.intl.d.ts",
|
|
||||||
"lib.es2020.number.d.ts",
|
|
||||||
"lib.es2020.promise.d.ts",
|
|
||||||
"lib.es2020.sharedmemory.d.ts",
|
|
||||||
"lib.es2020.string.d.ts",
|
|
||||||
"lib.es2020.symbol.wellknown.d.ts",
|
|
||||||
"lib.es2021.d.ts",
|
|
||||||
"lib.es2021.full.d.ts",
|
|
||||||
"lib.es2021.intl.d.ts",
|
|
||||||
"lib.es2021.promise.d.ts",
|
|
||||||
"lib.es2021.string.d.ts",
|
|
||||||
"lib.es2021.weakref.d.ts",
|
|
||||||
"lib.es2022.array.d.ts",
|
|
||||||
"lib.es2022.d.ts",
|
|
||||||
"lib.es2022.error.d.ts",
|
|
||||||
"lib.es2022.full.d.ts",
|
|
||||||
"lib.es2022.intl.d.ts",
|
|
||||||
"lib.es2022.object.d.ts",
|
|
||||||
"lib.es2022.regexp.d.ts",
|
|
||||||
"lib.es2022.string.d.ts",
|
|
||||||
"lib.es2023.array.d.ts",
|
|
||||||
"lib.es2023.collection.d.ts",
|
|
||||||
"lib.es2023.d.ts",
|
|
||||||
"lib.es2023.full.d.ts",
|
|
||||||
"lib.es2023.intl.d.ts",
|
|
||||||
"lib.es2024.arraybuffer.d.ts",
|
|
||||||
"lib.es2024.collection.d.ts",
|
|
||||||
"lib.es2024.d.ts",
|
|
||||||
"lib.es2024.full.d.ts",
|
|
||||||
"lib.es2024.object.d.ts",
|
|
||||||
"lib.es2024.promise.d.ts",
|
|
||||||
"lib.es2024.regexp.d.ts",
|
|
||||||
"lib.es2024.sharedmemory.d.ts",
|
|
||||||
"lib.es2024.string.d.ts",
|
|
||||||
"lib.es5.d.ts",
|
|
||||||
"lib.es6.d.ts",
|
|
||||||
"lib.esnext.array.d.ts",
|
|
||||||
"lib.esnext.collection.d.ts",
|
|
||||||
"lib.esnext.d.ts",
|
|
||||||
"lib.esnext.decorators.d.ts",
|
|
||||||
"lib.esnext.disposable.d.ts",
|
|
||||||
"lib.esnext.full.d.ts",
|
|
||||||
"lib.esnext.intl.d.ts",
|
|
||||||
"lib.esnext.iterator.d.ts",
|
|
||||||
"lib.scripthost.d.ts",
|
|
||||||
"lib.webworker.asynciterable.d.ts",
|
|
||||||
"lib.webworker.d.ts",
|
|
||||||
"lib.webworker.importscripts.d.ts",
|
|
||||||
"lib.webworker.iterable.d.ts",
|
|
||||||
];
|
|
||||||
for decl in decls {
|
|
||||||
let file = format!("./tsc/dts/{decl}");
|
|
||||||
compress_source(out_dir, &file);
|
|
||||||
}
|
}
|
||||||
let ext_decls = [
|
|
||||||
"console/lib.deno_console.d.ts",
|
#[op2]
|
||||||
"url/lib.deno_url.d.ts",
|
#[serde]
|
||||||
"web/lib.deno_web.d.ts",
|
// using the same op that is used in `tsc.rs` for loading modules and reading
|
||||||
"fetch/lib.deno_fetch.d.ts",
|
// files, but a slightly different implementation at build time.
|
||||||
"websocket/lib.deno_websocket.d.ts",
|
fn op_load(
|
||||||
"webstorage/lib.deno_webstorage.d.ts",
|
state: &mut OpState,
|
||||||
"canvas/lib.deno_canvas.d.ts",
|
#[string] load_specifier: &str,
|
||||||
"crypto/lib.deno_crypto.d.ts",
|
) -> Result<LoadResponse, JsErrorBox> {
|
||||||
"cache/lib.deno_cache.d.ts",
|
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
||||||
"net/lib.deno_net.d.ts",
|
let path_dts = state.borrow::<PathBuf>();
|
||||||
"broadcast_channel/lib.deno_broadcast_channel.d.ts",
|
let re_asset = lazy_regex::regex!(r"asset:/{3}lib\.(\S+)\.d\.ts");
|
||||||
];
|
|
||||||
for ext_decl in ext_decls {
|
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
|
||||||
let file = format!("../ext/{ext_decl}");
|
// parse out just the name so we can lookup the asset.
|
||||||
compress_source(out_dir, &file);
|
if let Some(caps) = re_asset.captures(load_specifier) {
|
||||||
|
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
|
||||||
|
// if it comes from an op crate, we were supplied with the path to the
|
||||||
|
// file.
|
||||||
|
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||||
|
PathBuf::from(op_crate_lib)
|
||||||
|
.canonicalize()
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
|
// otherwise we will generate the path ourself
|
||||||
|
} else {
|
||||||
|
path_dts.join(format!("lib.{lib}.d.ts"))
|
||||||
|
};
|
||||||
|
let data =
|
||||||
|
std::fs::read_to_string(path).map_err(JsErrorBox::from_err)?;
|
||||||
|
return Ok(LoadResponse {
|
||||||
|
data,
|
||||||
|
version: "1".to_string(),
|
||||||
|
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||||
|
script_kind: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(JsErrorBox::new(
|
||||||
|
"InvalidSpecifier",
|
||||||
|
format!("An invalid specifier was requested: {}", load_specifier),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn compress_source(out_dir: &Path, file: &str) {
|
deno_core::extension!(deno_tsc,
|
||||||
let path = Path::new(file)
|
ops = [
|
||||||
.canonicalize()
|
op_load,
|
||||||
.unwrap_or_else(|_| panic!("expected file \"{file}\" to exist"));
|
],
|
||||||
let contents = std::fs::read(&path).unwrap();
|
esm_entry_point = "ext:deno_tsc/99_main_compiler.js",
|
||||||
|
esm = [
|
||||||
|
dir "tsc",
|
||||||
|
"97_ts_host.js",
|
||||||
|
"98_lsp.js",
|
||||||
|
"99_main_compiler.js",
|
||||||
|
],
|
||||||
|
js = [
|
||||||
|
dir "tsc",
|
||||||
|
"00_typescript.js",
|
||||||
|
],
|
||||||
|
options = {
|
||||||
|
op_crate_libs: HashMap<&'static str, PathBuf>,
|
||||||
|
build_libs: Vec<&'static str>,
|
||||||
|
path_dts: PathBuf,
|
||||||
|
},
|
||||||
|
state = |state, options| {
|
||||||
|
state.put(options.op_crate_libs);
|
||||||
|
state.put(options.build_libs);
|
||||||
|
state.put(options.path_dts);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed={}", path.display());
|
pub fn create_compiler_snapshot(snapshot_path: PathBuf, cwd: &Path) {
|
||||||
|
// libs that are being provided by op crates.
|
||||||
|
let mut op_crate_libs = HashMap::new();
|
||||||
|
op_crate_libs.insert("deno.cache", deno_cache::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.console", deno_console::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.url", deno_url::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.web", deno_web::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration());
|
||||||
|
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.canvas", deno_canvas::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
|
||||||
|
op_crate_libs.insert(
|
||||||
|
"deno.broadcast_channel",
|
||||||
|
deno_broadcast_channel::get_declaration(),
|
||||||
|
);
|
||||||
|
op_crate_libs.insert("deno.net", deno_net::get_declaration());
|
||||||
|
|
||||||
let compressed = zstd::bulk::compress(&contents, 19).unwrap();
|
// ensure we invalidate the build properly.
|
||||||
let mut out = out_dir.join(file.trim_start_matches("../"));
|
for (_, path) in op_crate_libs.iter() {
|
||||||
let mut ext = out
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
.extension()
|
}
|
||||||
.map(|s| s.to_string_lossy())
|
|
||||||
.unwrap_or_default()
|
// libs that should be loaded into the isolate before snapshotting.
|
||||||
.into_owned();
|
let libs = vec![
|
||||||
ext.push_str(".zstd");
|
// Deno custom type libraries
|
||||||
out.set_extension(ext);
|
"deno.window",
|
||||||
std::fs::create_dir_all(out.parent().unwrap()).unwrap();
|
"deno.worker",
|
||||||
let mut file = std::fs::OpenOptions::new()
|
"deno.shared_globals",
|
||||||
.create(true)
|
"deno.ns",
|
||||||
.truncate(true)
|
"deno.unstable",
|
||||||
.write(true)
|
// Deno built-in type libraries
|
||||||
.open(out)
|
"decorators",
|
||||||
.unwrap();
|
"decorators.legacy",
|
||||||
file
|
"dom.asynciterable",
|
||||||
.write_all(&(contents.len() as u32).to_le_bytes())
|
"dom",
|
||||||
|
"dom.extras",
|
||||||
|
"dom.iterable",
|
||||||
|
"es2015.collection",
|
||||||
|
"es2015.core",
|
||||||
|
"es2015",
|
||||||
|
"es2015.generator",
|
||||||
|
"es2015.iterable",
|
||||||
|
"es2015.promise",
|
||||||
|
"es2015.proxy",
|
||||||
|
"es2015.reflect",
|
||||||
|
"es2015.symbol",
|
||||||
|
"es2015.symbol.wellknown",
|
||||||
|
"es2016.array.include",
|
||||||
|
"es2016",
|
||||||
|
"es2016.full",
|
||||||
|
"es2016.intl",
|
||||||
|
"es2017.arraybuffer",
|
||||||
|
"es2017",
|
||||||
|
"es2017.date",
|
||||||
|
"es2017.full",
|
||||||
|
"es2017.intl",
|
||||||
|
"es2017.object",
|
||||||
|
"es2017.sharedmemory",
|
||||||
|
"es2017.string",
|
||||||
|
"es2017.typedarrays",
|
||||||
|
"es2018.asyncgenerator",
|
||||||
|
"es2018.asynciterable",
|
||||||
|
"es2018",
|
||||||
|
"es2018.full",
|
||||||
|
"es2018.intl",
|
||||||
|
"es2018.promise",
|
||||||
|
"es2018.regexp",
|
||||||
|
"es2019.array",
|
||||||
|
"es2019",
|
||||||
|
"es2019.full",
|
||||||
|
"es2019.intl",
|
||||||
|
"es2019.object",
|
||||||
|
"es2019.string",
|
||||||
|
"es2019.symbol",
|
||||||
|
"es2020.bigint",
|
||||||
|
"es2020",
|
||||||
|
"es2020.date",
|
||||||
|
"es2020.full",
|
||||||
|
"es2020.intl",
|
||||||
|
"es2020.number",
|
||||||
|
"es2020.promise",
|
||||||
|
"es2020.sharedmemory",
|
||||||
|
"es2020.string",
|
||||||
|
"es2020.symbol.wellknown",
|
||||||
|
"es2021",
|
||||||
|
"es2021.full",
|
||||||
|
"es2021.intl",
|
||||||
|
"es2021.promise",
|
||||||
|
"es2021.string",
|
||||||
|
"es2021.weakref",
|
||||||
|
"es2022.array",
|
||||||
|
"es2022",
|
||||||
|
"es2022.error",
|
||||||
|
"es2022.full",
|
||||||
|
"es2022.intl",
|
||||||
|
"es2022.object",
|
||||||
|
"es2022.regexp",
|
||||||
|
"es2022.string",
|
||||||
|
"es2023.array",
|
||||||
|
"es2023.collection",
|
||||||
|
"es2023",
|
||||||
|
"es2023.full",
|
||||||
|
"es2023.intl",
|
||||||
|
"es2024.arraybuffer",
|
||||||
|
"es2024.collection",
|
||||||
|
"es2024",
|
||||||
|
"es2024.full",
|
||||||
|
"es2024.object",
|
||||||
|
"es2024.promise",
|
||||||
|
"es2024.regexp",
|
||||||
|
"es2024.sharedmemory",
|
||||||
|
"es2024.string",
|
||||||
|
"es5",
|
||||||
|
"es6",
|
||||||
|
"esnext.array",
|
||||||
|
"esnext.collection",
|
||||||
|
"esnext",
|
||||||
|
"esnext.decorators",
|
||||||
|
"esnext.disposable",
|
||||||
|
"esnext.full",
|
||||||
|
"esnext.intl",
|
||||||
|
"esnext.iterator",
|
||||||
|
"scripthost",
|
||||||
|
"webworker.asynciterable",
|
||||||
|
"webworker",
|
||||||
|
"webworker.importscripts",
|
||||||
|
"webworker.iterable",
|
||||||
|
];
|
||||||
|
|
||||||
|
let path_dts = cwd.join("tsc/dts");
|
||||||
|
// ensure we invalidate the build properly.
|
||||||
|
for name in libs.iter() {
|
||||||
|
println!(
|
||||||
|
"cargo:rerun-if-changed={}",
|
||||||
|
path_dts.join(format!("lib.{name}.d.ts")).display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a copy of the vector that includes any op crate libs to be passed
|
||||||
|
// to the JavaScript compiler to build into the snapshot
|
||||||
|
let mut build_libs = libs.clone();
|
||||||
|
for (op_lib, _) in op_crate_libs.iter() {
|
||||||
|
build_libs.push(op_lib.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// used in the tests to verify that after snapshotting it has the same number
|
||||||
|
// of lib files loaded and hasn't included any ones lazily loaded from Rust
|
||||||
|
std::fs::write(
|
||||||
|
PathBuf::from(env::var_os("OUT_DIR").unwrap())
|
||||||
|
.join("lib_file_names.json"),
|
||||||
|
serde_json::to_string(&build_libs).unwrap(),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
file.write_all(&compressed).unwrap();
|
// Leak to satisfy type-checker. It's okay since it's only run once for a build script.
|
||||||
}
|
let build_libs_ = Box::leak(Box::new(build_libs.clone()));
|
||||||
|
let runtime_cb = Box::new(|rt: &mut deno_core::JsRuntimeForSnapshot| {
|
||||||
|
let scope = &mut rt.handle_scope();
|
||||||
|
|
||||||
fn compress_sources(out_dir: &Path) {
|
let context = scope.get_current_context();
|
||||||
compress_decls(out_dir);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let ext_sources = [
|
let name = v8::String::new(scope, "snapshot").unwrap();
|
||||||
"./tsc/99_main_compiler.js",
|
let snapshot_fn_val = global.get(scope, name.into()).unwrap();
|
||||||
"./tsc/97_ts_host.js",
|
let snapshot_fn: v8::Local<v8::Function> =
|
||||||
"./tsc/98_lsp.js",
|
snapshot_fn_val.try_into().unwrap();
|
||||||
"./tsc/00_typescript.js",
|
let undefined = v8::undefined(scope);
|
||||||
];
|
let build_libs = build_libs_.clone();
|
||||||
for ext_source in ext_sources {
|
let build_libs_v8 =
|
||||||
compress_source(out_dir, ext_source);
|
deno_core::serde_v8::to_v8(scope, build_libs).unwrap();
|
||||||
|
|
||||||
|
snapshot_fn
|
||||||
|
.call(scope, undefined.into(), &[build_libs_v8])
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
let output = create_snapshot(
|
||||||
|
CreateSnapshotOptions {
|
||||||
|
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
|
||||||
|
startup_snapshot: None,
|
||||||
|
extensions: vec![deno_tsc::init_ops_and_esm(
|
||||||
|
op_crate_libs,
|
||||||
|
build_libs,
|
||||||
|
path_dts,
|
||||||
|
)],
|
||||||
|
extension_transpiler: None,
|
||||||
|
with_runtime_cb: Some(runtime_cb),
|
||||||
|
skip_op_registration: false,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// NOTE(bartlomieju): Compressing the TSC snapshot in debug build took
|
||||||
|
// ~45s on M1 MacBook Pro; without compression it took ~1s.
|
||||||
|
// Thus we're not using compressed snapshot, trading off
|
||||||
|
// a lot of build time for some startup time in debug build.
|
||||||
|
let mut file = std::fs::File::create(snapshot_path).unwrap();
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
file.write_all(&output.output).unwrap();
|
||||||
|
} else {
|
||||||
|
let mut vec = Vec::with_capacity(output.output.len());
|
||||||
|
vec.extend((output.output.len() as u32).to_le_bytes());
|
||||||
|
vec.extend_from_slice(
|
||||||
|
&zstd::bulk::compress(&output.output, 22)
|
||||||
|
.expect("snapshot compression failed"),
|
||||||
|
);
|
||||||
|
file.write_all(&vec).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for path in output.files_loaded_during_snapshot {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,12 +337,6 @@ fn main() {
|
||||||
// To debug snapshot issues uncomment:
|
// To debug snapshot issues uncomment:
|
||||||
// op_fetch_asset::trace_serializer();
|
// op_fetch_asset::trace_serializer();
|
||||||
|
|
||||||
if !cfg!(debug_assertions) {
|
|
||||||
let out_dir =
|
|
||||||
std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
|
|
||||||
compress_sources(&out_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(c) = env::var("DENO_CANARY") {
|
if let Ok(c) = env::var("DENO_CANARY") {
|
||||||
println!("cargo:rustc-env=DENO_CANARY={c}");
|
println!("cargo:rustc-env=DENO_CANARY={c}");
|
||||||
}
|
}
|
||||||
|
@ -216,6 +345,12 @@ fn main() {
|
||||||
println!("cargo:rustc-env=TARGET={}", env::var("TARGET").unwrap());
|
println!("cargo:rustc-env=TARGET={}", env::var("TARGET").unwrap());
|
||||||
println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
|
println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
|
||||||
|
|
||||||
|
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
||||||
|
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
|
let compiler_snapshot_path = o.join("COMPILER_SNAPSHOT.bin");
|
||||||
|
ts::create_compiler_snapshot(compiler_snapshot_path, &c);
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
let mut res = winres::WindowsResource::new();
|
let mut res = winres::WindowsResource::new();
|
||||||
|
@ -227,3 +362,11 @@ fn main() {
|
||||||
res.compile().unwrap();
|
res.compile().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deno_webgpu_get_declaration() -> PathBuf {
|
||||||
|
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
manifest_dir
|
||||||
|
.join("tsc")
|
||||||
|
.join("dts")
|
||||||
|
.join("lib.deno_webgpu.d.ts")
|
||||||
|
}
|
||||||
|
|
|
@ -606,7 +606,7 @@ impl Inner {
|
||||||
ts_server.clone(),
|
ts_server.clone(),
|
||||||
diagnostics_state.clone(),
|
diagnostics_state.clone(),
|
||||||
);
|
);
|
||||||
let assets = Assets::new();
|
let assets = Assets::new(ts_server.clone());
|
||||||
let initial_cwd = std::env::current_dir().unwrap_or_else(|_| {
|
let initial_cwd = std::env::current_dir().unwrap_or_else(|_| {
|
||||||
panic!("Could not resolve current working directory")
|
panic!("Could not resolve current working directory")
|
||||||
});
|
});
|
||||||
|
@ -913,6 +913,7 @@ impl Inner {
|
||||||
.await?;
|
.await?;
|
||||||
self.ts_fixable_diagnostics = fixable_diagnostics;
|
self.ts_fixable_diagnostics = fixable_diagnostics;
|
||||||
}
|
}
|
||||||
|
self.assets.initialize(self.snapshot()).await;
|
||||||
|
|
||||||
self.performance.measure(mark);
|
self.performance.measure(mark);
|
||||||
Ok(InitializeResult {
|
Ok(InitializeResult {
|
||||||
|
|
127
cli/lsp/tsc.rs
127
cli/lsp/tsc.rs
|
@ -1399,7 +1399,7 @@ fn new_assets_map() -> Arc<Mutex<AssetsMap>> {
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
let url_str = format!("asset:///{k}");
|
let url_str = format!("asset:///{k}");
|
||||||
let specifier = resolve_url(&url_str).unwrap();
|
let specifier = resolve_url(&url_str).unwrap();
|
||||||
let asset = AssetDocument::new(specifier.clone(), v.get());
|
let asset = AssetDocument::new(specifier.clone(), v);
|
||||||
(specifier, asset)
|
(specifier, asset)
|
||||||
})
|
})
|
||||||
.collect::<AssetsMap>();
|
.collect::<AssetsMap>();
|
||||||
|
@ -1430,16 +1430,29 @@ impl AssetsSnapshot {
|
||||||
/// multiple threads without needing to worry about race conditions.
|
/// multiple threads without needing to worry about race conditions.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Assets {
|
pub struct Assets {
|
||||||
|
ts_server: Arc<TsServer>,
|
||||||
assets: Arc<Mutex<AssetsMap>>,
|
assets: Arc<Mutex<AssetsMap>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assets {
|
impl Assets {
|
||||||
pub fn new() -> Self {
|
pub fn new(ts_server: Arc<TsServer>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
ts_server,
|
||||||
assets: new_assets_map(),
|
assets: new_assets_map(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initializes with the assets in the isolate.
|
||||||
|
pub async fn initialize(&self, state_snapshot: Arc<StateSnapshot>) {
|
||||||
|
let assets = get_isolate_assets(&self.ts_server, state_snapshot).await;
|
||||||
|
let mut assets_map = self.assets.lock();
|
||||||
|
for asset in assets {
|
||||||
|
if !assets_map.contains_key(asset.specifier()) {
|
||||||
|
assets_map.insert(asset.specifier().clone(), asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn snapshot(&self) -> AssetsSnapshot {
|
pub fn snapshot(&self) -> AssetsSnapshot {
|
||||||
// it's ok to not make a complete copy for snapshotting purposes
|
// it's ok to not make a complete copy for snapshotting purposes
|
||||||
// because assets are static
|
// because assets are static
|
||||||
|
@ -1464,6 +1477,39 @@ impl Assets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get all the assets stored in the tsc isolate.
|
||||||
|
async fn get_isolate_assets(
|
||||||
|
ts_server: &TsServer,
|
||||||
|
state_snapshot: Arc<StateSnapshot>,
|
||||||
|
) -> Vec<AssetDocument> {
|
||||||
|
let req = TscRequest::GetAssets;
|
||||||
|
let res: Value = ts_server
|
||||||
|
.request(state_snapshot, req, None, &Default::default())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let response_assets = match res {
|
||||||
|
Value::Array(value) => value,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let mut assets = Vec::with_capacity(response_assets.len());
|
||||||
|
|
||||||
|
for asset in response_assets {
|
||||||
|
let mut obj = match asset {
|
||||||
|
Value::Object(obj) => obj,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let specifier_str = obj.get("specifier").unwrap().as_str().unwrap();
|
||||||
|
let specifier = ModuleSpecifier::parse(specifier_str).unwrap();
|
||||||
|
let text = match obj.remove("text").unwrap() {
|
||||||
|
Value::String(text) => text,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
assets.push(AssetDocument::new(specifier, text));
|
||||||
|
}
|
||||||
|
|
||||||
|
assets
|
||||||
|
}
|
||||||
|
|
||||||
fn get_tag_body_text(
|
fn get_tag_body_text(
|
||||||
tag: &JsDocTagInfo,
|
tag: &JsDocTagInfo,
|
||||||
language_server: &language_server::Inner,
|
language_server: &language_server::Inner,
|
||||||
|
@ -4501,21 +4547,6 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
|
||||||
#[serde]
|
|
||||||
fn op_libs() -> Vec<String> {
|
|
||||||
let mut out =
|
|
||||||
Vec::with_capacity(crate::tsc::LAZILY_LOADED_STATIC_ASSETS.len());
|
|
||||||
for key in crate::tsc::LAZILY_LOADED_STATIC_ASSETS.keys() {
|
|
||||||
let lib = key
|
|
||||||
.replace("lib.", "")
|
|
||||||
.replace(".d.ts", "")
|
|
||||||
.replace("deno_", "deno.");
|
|
||||||
out.push(lib);
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
enum LoadError {
|
enum LoadError {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
|
@ -4916,13 +4947,13 @@ fn run_tsc_thread(
|
||||||
// supplied snapshot is an isolate that contains the TypeScript language
|
// supplied snapshot is an isolate that contains the TypeScript language
|
||||||
// server.
|
// server.
|
||||||
let mut tsc_runtime = JsRuntime::new(RuntimeOptions {
|
let mut tsc_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
extensions: vec![deno_tsc::init_ops_and_esm(
|
extensions: vec![deno_tsc::init_ops(
|
||||||
performance,
|
performance,
|
||||||
specifier_map,
|
specifier_map,
|
||||||
request_rx,
|
request_rx,
|
||||||
)],
|
)],
|
||||||
create_params: create_isolate_create_params(),
|
create_params: create_isolate_create_params(),
|
||||||
startup_snapshot: None,
|
startup_snapshot: Some(tsc::compiler_snapshot()),
|
||||||
inspector: has_inspector_server,
|
inspector: has_inspector_server,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
@ -5004,7 +5035,6 @@ deno_core::extension!(deno_tsc,
|
||||||
op_script_version,
|
op_script_version,
|
||||||
op_project_version,
|
op_project_version,
|
||||||
op_poll_requests,
|
op_poll_requests,
|
||||||
op_libs,
|
|
||||||
],
|
],
|
||||||
options = {
|
options = {
|
||||||
performance: Arc<Performance>,
|
performance: Arc<Performance>,
|
||||||
|
@ -5019,14 +5049,6 @@ deno_core::extension!(deno_tsc,
|
||||||
options.request_rx,
|
options.request_rx,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
customizer = |ext: &mut deno_core::Extension| {
|
|
||||||
use deno_core::ExtensionFileSource;
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_tsc/99_main_compiler.js", crate::tsc::MAIN_COMPILER_SOURCE.get().into()));
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_tsc/97_ts_host.js", crate::tsc::TS_HOST_SOURCE.get().into()));
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_tsc/98_lsp.js", crate::tsc::LSP_SOURCE.get().into()));
|
|
||||||
ext.js_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_cli_tsc/00_typescript.js", crate::tsc::TYPESCRIPT_SOURCE.get().into()));
|
|
||||||
ext.esm_entry_point = Some("ext:deno_tsc/99_main_compiler.js");
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize_repr, Serialize_repr)]
|
#[derive(Debug, Clone, Deserialize_repr, Serialize_repr)]
|
||||||
|
@ -5406,6 +5428,7 @@ pub struct JsNull;
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub enum TscRequest {
|
pub enum TscRequest {
|
||||||
GetDiagnostics((Vec<String>, usize)),
|
GetDiagnostics((Vec<String>, usize)),
|
||||||
|
GetAssets,
|
||||||
|
|
||||||
CleanupSemanticCache,
|
CleanupSemanticCache,
|
||||||
// https://github.com/denoland/deno/blob/v1.37.1/cli/tsc/dts/typescript.d.ts#L6230
|
// https://github.com/denoland/deno/blob/v1.37.1/cli/tsc/dts/typescript.d.ts#L6230
|
||||||
|
@ -5611,6 +5634,7 @@ impl TscRequest {
|
||||||
("provideInlayHints", Some(serde_v8::to_v8(scope, args)?))
|
("provideInlayHints", Some(serde_v8::to_v8(scope, args)?))
|
||||||
}
|
}
|
||||||
TscRequest::CleanupSemanticCache => ("cleanupSemanticCache", None),
|
TscRequest::CleanupSemanticCache => ("cleanupSemanticCache", None),
|
||||||
|
TscRequest::GetAssets => ("$getAssets", None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(args)
|
Ok(args)
|
||||||
|
@ -5655,6 +5679,7 @@ impl TscRequest {
|
||||||
TscRequest::GetSignatureHelpItems(_) => "getSignatureHelpItems",
|
TscRequest::GetSignatureHelpItems(_) => "getSignatureHelpItems",
|
||||||
TscRequest::GetNavigateToItems(_) => "getNavigateToItems",
|
TscRequest::GetNavigateToItems(_) => "getNavigateToItems",
|
||||||
TscRequest::ProvideInlayHints(_) => "provideInlayHints",
|
TscRequest::ProvideInlayHints(_) => "provideInlayHints",
|
||||||
|
TscRequest::GetAssets => "$getAssets",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6040,6 +6065,52 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_request_assets() {
|
||||||
|
let (_, ts_server, snapshot, _) = setup(json!({}), &[]).await;
|
||||||
|
let assets = get_isolate_assets(&ts_server, snapshot).await;
|
||||||
|
let mut asset_names = assets
|
||||||
|
.iter()
|
||||||
|
.map(|a| {
|
||||||
|
a.specifier()
|
||||||
|
.to_string()
|
||||||
|
.replace("asset:///lib.", "")
|
||||||
|
.replace(".d.ts", "")
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut expected_asset_names: Vec<String> = serde_json::from_str(
|
||||||
|
include_str!(concat!(env!("OUT_DIR"), "/lib_file_names.json")),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
asset_names.sort();
|
||||||
|
|
||||||
|
// if this test fails, update build.rs
|
||||||
|
expected_asset_names.sort();
|
||||||
|
assert_eq!(asset_names, expected_asset_names);
|
||||||
|
|
||||||
|
// get some notification when the size of the assets grows
|
||||||
|
let mut total_size = 0;
|
||||||
|
for asset in &assets {
|
||||||
|
total_size += asset.text().len();
|
||||||
|
}
|
||||||
|
assert!(total_size > 0);
|
||||||
|
#[allow(clippy::print_stderr)]
|
||||||
|
// currently as of TS 5.7, it's 3MB
|
||||||
|
if total_size > 3_500_000 {
|
||||||
|
let mut sizes = Vec::new();
|
||||||
|
for asset in &assets {
|
||||||
|
sizes.push((asset.specifier(), asset.text().len()));
|
||||||
|
}
|
||||||
|
sizes.sort_by_cached_key(|(_, size)| *size);
|
||||||
|
sizes.reverse();
|
||||||
|
for (specifier, size) in &sizes {
|
||||||
|
eprintln!("{}: {}", specifier, size);
|
||||||
|
}
|
||||||
|
eprintln!("Total size: {}", total_size);
|
||||||
|
panic!("Assets were quite large.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_modify_sources() {
|
async fn test_modify_sources() {
|
||||||
let (temp_dir, ts_server, snapshot, cache) = setup(
|
let (temp_dir, ts_server, snapshot, cache) = setup(
|
||||||
|
|
|
@ -855,3 +855,17 @@ const setTypesNodeIgnorableNames = new Set([
|
||||||
"WritableStreamDefaultWriter",
|
"WritableStreamDefaultWriter",
|
||||||
]);
|
]);
|
||||||
ts.deno.setTypesNodeIgnorableNames(setTypesNodeIgnorableNames);
|
ts.deno.setTypesNodeIgnorableNames(setTypesNodeIgnorableNames);
|
||||||
|
|
||||||
|
export function getAssets() {
|
||||||
|
/** @type {{ specifier: string; text: string; }[]} */
|
||||||
|
const assets = [];
|
||||||
|
for (const sourceFile of SOURCE_FILE_CACHE.values()) {
|
||||||
|
if (sourceFile.fileName.startsWith(ASSETS_URL_PREFIX)) {
|
||||||
|
assets.push({
|
||||||
|
specifier: sourceFile.fileName,
|
||||||
|
text: sourceFile.text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assets;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
error,
|
error,
|
||||||
filterMapDiagnostic,
|
filterMapDiagnostic,
|
||||||
fromTypeScriptDiagnostics,
|
fromTypeScriptDiagnostics,
|
||||||
|
getAssets,
|
||||||
getCreateSourceFileOptions,
|
getCreateSourceFileOptions,
|
||||||
host,
|
host,
|
||||||
IS_NODE_SOURCE_FILE_CACHE,
|
IS_NODE_SOURCE_FILE_CACHE,
|
||||||
|
@ -445,6 +446,9 @@ function serverRequest(id, method, args, scope, maybeChange) {
|
||||||
ts.getSupportedCodeFixes(),
|
ts.getSupportedCodeFixes(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case "$getAssets": {
|
||||||
|
return respond(id, getAssets());
|
||||||
|
}
|
||||||
case "$getDiagnostics": {
|
case "$getDiagnostics": {
|
||||||
const projectVersion = args[1];
|
const projectVersion = args[1];
|
||||||
// there's a possibility that we receive a change notification
|
// there's a possibility that we receive a change notification
|
||||||
|
|
|
@ -13,10 +13,13 @@
|
||||||
delete Object.prototype.__proto__;
|
delete Object.prototype.__proto__;
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
assert,
|
||||||
AssertionError,
|
AssertionError,
|
||||||
|
ASSETS_URL_PREFIX,
|
||||||
debug,
|
debug,
|
||||||
filterMapDiagnostic,
|
filterMapDiagnostic,
|
||||||
fromTypeScriptDiagnostics,
|
fromTypeScriptDiagnostics,
|
||||||
|
getAssets,
|
||||||
host,
|
host,
|
||||||
setLogDebug,
|
setLogDebug,
|
||||||
} from "./97_ts_host.js";
|
} from "./97_ts_host.js";
|
||||||
|
@ -211,20 +214,31 @@ function exec({ config, debug: debugFlag, rootNames, localOnly }) {
|
||||||
debug("<<< exec stop");
|
debug("<<< exec stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
const libs = ops.op_libs();
|
globalThis.snapshot = function (libs) {
|
||||||
for (const lib of libs) {
|
for (const lib of libs) {
|
||||||
const specifier = `lib.${lib}.d.ts`;
|
const specifier = `lib.${lib}.d.ts`;
|
||||||
// we are using internal APIs here to "inject" our custom libraries into
|
// we are using internal APIs here to "inject" our custom libraries into
|
||||||
// tsc, so things like `"lib": [ "deno.ns" ]` are supported.
|
// tsc, so things like `"lib": [ "deno.ns" ]` are supported.
|
||||||
if (!ts.libs.includes(lib)) {
|
if (!ts.libs.includes(lib)) {
|
||||||
ts.libs.push(lib);
|
ts.libs.push(lib);
|
||||||
ts.libMap.set(lib, specifier);
|
ts.libMap.set(lib, `lib.${lib}.d.ts`);
|
||||||
|
}
|
||||||
|
// we are caching in memory common type libraries that will be re-used by
|
||||||
|
// tsc on when the snapshot is restored
|
||||||
|
assert(
|
||||||
|
!!host.getSourceFile(
|
||||||
|
`${ASSETS_URL_PREFIX}${specifier}`,
|
||||||
|
ts.ScriptTarget.ESNext,
|
||||||
|
),
|
||||||
|
`failed to load '${ASSETS_URL_PREFIX}${specifier}'`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// exposes the functions that are called by `tsc::exec()` when type
|
// exposes the functions that are called by `tsc::exec()` when type
|
||||||
// checking TypeScript.
|
// checking TypeScript.
|
||||||
globalThis.exec = exec;
|
globalThis.exec = exec;
|
||||||
|
globalThis.getAssets = getAssets;
|
||||||
|
|
||||||
// exposes the functions that are called when the compiler is used as a
|
// exposes the functions that are called when the compiler is used as a
|
||||||
// language service.
|
// language service.
|
||||||
|
|
512
cli/tsc/mod.rs
512
cli/tsc/mod.rs
|
@ -5,10 +5,10 @@ use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
|
use deno_core::ascii_str;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
|
@ -18,6 +18,7 @@ use deno_core::serde::Deserializer;
|
||||||
use deno_core::serde::Serialize;
|
use deno_core::serde::Serialize;
|
||||||
use deno_core::serde::Serializer;
|
use deno_core::serde::Serializer;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
|
use deno_core::serde_v8;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::JsRuntime;
|
use deno_core::JsRuntime;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
@ -58,8 +59,33 @@ pub use self::diagnostics::DiagnosticCategory;
|
||||||
pub use self::diagnostics::Diagnostics;
|
pub use self::diagnostics::Diagnostics;
|
||||||
pub use self::diagnostics::Position;
|
pub use self::diagnostics::Position;
|
||||||
|
|
||||||
|
pub static COMPILER_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
|| {
|
||||||
|
static COMPRESSED_COMPILER_SNAPSHOT: &[u8] =
|
||||||
|
include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.bin"));
|
||||||
|
|
||||||
|
// NOTE(bartlomieju): Compressing the TSC snapshot in debug build took
|
||||||
|
// ~45s on M1 MacBook Pro; without compression it took ~1s.
|
||||||
|
// Thus we're not using compressed snapshot, trading off
|
||||||
|
// a lot of build time for some startup time in debug build.
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
return COMPRESSED_COMPILER_SNAPSHOT.to_vec().into_boxed_slice();
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
zstd::bulk::decompress(
|
||||||
|
&COMPRESSED_COMPILER_SNAPSHOT[4..],
|
||||||
|
u32::from_le_bytes(COMPRESSED_COMPILER_SNAPSHOT[0..4].try_into().unwrap())
|
||||||
|
as usize,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.into_boxed_slice()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
pub fn get_types_declaration_file_text() -> String {
|
pub fn get_types_declaration_file_text() -> String {
|
||||||
let mut assets = get_asset_texts()
|
let mut assets = get_asset_texts_from_new_runtime()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| (a.specifier, a.text))
|
.map(|a| (a.specifier, a.text))
|
||||||
|
@ -94,146 +120,41 @@ pub fn get_types_declaration_file_text() -> String {
|
||||||
.join("\n")
|
.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_asset_texts() -> Result<Vec<AssetText>, AnyError> {
|
fn get_asset_texts_from_new_runtime() -> Result<Vec<AssetText>, AnyError> {
|
||||||
let mut out = Vec::with_capacity(LAZILY_LOADED_STATIC_ASSETS.len());
|
deno_core::extension!(
|
||||||
for (name, text) in LAZILY_LOADED_STATIC_ASSETS.iter() {
|
deno_cli_tsc,
|
||||||
out.push(AssetText {
|
ops = [
|
||||||
specifier: format!("asset:///{name}"),
|
op_create_hash,
|
||||||
text: text.to_string(),
|
op_emit,
|
||||||
});
|
op_is_node_file,
|
||||||
}
|
op_load,
|
||||||
Ok(out)
|
op_remap_specifier,
|
||||||
|
op_resolve,
|
||||||
|
op_respond,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// the assets are stored within the typescript isolate, so take them out of there
|
||||||
|
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||||
|
startup_snapshot: Some(compiler_snapshot()),
|
||||||
|
extensions: vec![deno_cli_tsc::init_ops()],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let global = runtime
|
||||||
|
.execute_script("get_assets.js", ascii_str!("globalThis.getAssets()"))?;
|
||||||
|
let scope = &mut runtime.handle_scope();
|
||||||
|
let local = deno_core::v8::Local::new(scope, global);
|
||||||
|
Ok(serde_v8::from_v8::<Vec<AssetText>>(scope, local)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! maybe_compressed_source {
|
pub fn compiler_snapshot() -> &'static [u8] {
|
||||||
($file: expr) => {{
|
&COMPILER_SNAPSHOT
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
StaticAssetSource::Uncompressed(include_str!(concat!(
|
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
|
||||||
"/",
|
|
||||||
$file
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
{
|
|
||||||
StaticAssetSource::Compressed(CompressedSource::new(include_bytes!(
|
|
||||||
concat!(env!("OUT_DIR"), "/", $file, ".zstd")
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
(compressed = $comp: expr, uncompressed = $uncomp: expr) => {{
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
StaticAssetSource::Uncompressed(include_str!(concat!(
|
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
|
||||||
"/",
|
|
||||||
$uncomp
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
{
|
|
||||||
StaticAssetSource::Compressed(CompressedSource::new(include_bytes!(
|
|
||||||
concat!(env!("OUT_DIR"), "/", $comp, ".zstd")
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! maybe_compressed_lib {
|
macro_rules! inc {
|
||||||
($name: expr, $file: expr) => {
|
($e:expr) => {
|
||||||
($name, maybe_compressed_source!(concat!("tsc/dts/", $file)))
|
include_str!(concat!("./dts/", $e))
|
||||||
};
|
};
|
||||||
($e: expr) => {
|
|
||||||
maybe_compressed_lib!($e, $e)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! maybe_compressed_ext_lib {
|
|
||||||
($name: expr, $file: expr) => {
|
|
||||||
(
|
|
||||||
$name,
|
|
||||||
maybe_compressed_source!(
|
|
||||||
compressed = concat!("ext/", $file),
|
|
||||||
uncompressed = concat!("../ext/", $file)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum StaticAssetSource {
|
|
||||||
#[cfg_attr(debug_assertions, allow(dead_code))]
|
|
||||||
Compressed(CompressedSource),
|
|
||||||
Uncompressed(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Like a `Cow` but the owned form is an `Arc<str>` instead of `String`
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum MaybeStaticSource {
|
|
||||||
Computed(Arc<str>),
|
|
||||||
Static(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for MaybeStaticSource {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
MaybeStaticSource::Computed(arc) => write!(f, "{}", arc),
|
|
||||||
MaybeStaticSource::Static(s) => write!(f, "{}", s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<MaybeStaticSource> for Cow<'static, str> {
|
|
||||||
fn from(value: MaybeStaticSource) -> Self {
|
|
||||||
match value {
|
|
||||||
MaybeStaticSource::Computed(arc) => Cow::Owned(arc.to_string()),
|
|
||||||
MaybeStaticSource::Static(s) => Cow::Borrowed(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<str> for MaybeStaticSource {
|
|
||||||
fn as_ref(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
MaybeStaticSource::Computed(arc) => arc.as_ref(),
|
|
||||||
MaybeStaticSource::Static(s) => s,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<MaybeStaticSource> for String {
|
|
||||||
fn from(value: MaybeStaticSource) -> Self {
|
|
||||||
match value {
|
|
||||||
MaybeStaticSource::Computed(arc) => arc.to_string(),
|
|
||||||
MaybeStaticSource::Static(s) => s.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<MaybeStaticSource> for Arc<str> {
|
|
||||||
fn from(value: MaybeStaticSource) -> Self {
|
|
||||||
match value {
|
|
||||||
MaybeStaticSource::Computed(arc) => arc,
|
|
||||||
MaybeStaticSource::Static(s) => Arc::from(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StaticAssetSource {
|
|
||||||
pub fn get(&self) -> MaybeStaticSource {
|
|
||||||
match self {
|
|
||||||
StaticAssetSource::Compressed(compressed_source) => {
|
|
||||||
MaybeStaticSource::Computed(compressed_source.get())
|
|
||||||
}
|
|
||||||
StaticAssetSource::Uncompressed(src) => MaybeStaticSource::Static(src),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::inherent_to_string)]
|
|
||||||
pub fn to_string(&self) -> String {
|
|
||||||
self.get().into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains static assets that are not preloaded in the compiler snapshot.
|
/// Contains static assets that are not preloaded in the compiler snapshot.
|
||||||
|
@ -241,154 +162,40 @@ impl StaticAssetSource {
|
||||||
/// We lazily load these because putting them in the compiler snapshot will
|
/// We lazily load these because putting them in the compiler snapshot will
|
||||||
/// increase memory usage when not used (last time checked by about 0.5MB).
|
/// increase memory usage when not used (last time checked by about 0.5MB).
|
||||||
pub static LAZILY_LOADED_STATIC_ASSETS: Lazy<
|
pub static LAZILY_LOADED_STATIC_ASSETS: Lazy<
|
||||||
HashMap<&'static str, StaticAssetSource>,
|
HashMap<&'static str, &'static str>,
|
||||||
> = Lazy::new(|| {
|
> = Lazy::new(|| {
|
||||||
([
|
([
|
||||||
// compressed in build.rs
|
(
|
||||||
maybe_compressed_ext_lib!(
|
"lib.dom.asynciterable.d.ts",
|
||||||
"lib.deno.console.d.ts",
|
inc!("lib.dom.asynciterable.d.ts"),
|
||||||
"console/lib.deno_console.d.ts"
|
|
||||||
),
|
),
|
||||||
maybe_compressed_ext_lib!("lib.deno.url.d.ts", "url/lib.deno_url.d.ts"),
|
("lib.dom.d.ts", inc!("lib.dom.d.ts")),
|
||||||
maybe_compressed_ext_lib!("lib.deno.web.d.ts", "web/lib.deno_web.d.ts"),
|
("lib.dom.extras.d.ts", inc!("lib.dom.extras.d.ts")),
|
||||||
maybe_compressed_ext_lib!(
|
("lib.dom.iterable.d.ts", inc!("lib.dom.iterable.d.ts")),
|
||||||
"lib.deno.fetch.d.ts",
|
("lib.es6.d.ts", inc!("lib.es6.d.ts")),
|
||||||
"fetch/lib.deno_fetch.d.ts"
|
("lib.es2016.full.d.ts", inc!("lib.es2016.full.d.ts")),
|
||||||
|
("lib.es2017.full.d.ts", inc!("lib.es2017.full.d.ts")),
|
||||||
|
("lib.es2018.full.d.ts", inc!("lib.es2018.full.d.ts")),
|
||||||
|
("lib.es2019.full.d.ts", inc!("lib.es2019.full.d.ts")),
|
||||||
|
("lib.es2020.full.d.ts", inc!("lib.es2020.full.d.ts")),
|
||||||
|
("lib.es2021.full.d.ts", inc!("lib.es2021.full.d.ts")),
|
||||||
|
("lib.es2022.full.d.ts", inc!("lib.es2022.full.d.ts")),
|
||||||
|
("lib.esnext.full.d.ts", inc!("lib.esnext.full.d.ts")),
|
||||||
|
("lib.scripthost.d.ts", inc!("lib.scripthost.d.ts")),
|
||||||
|
("lib.webworker.d.ts", inc!("lib.webworker.d.ts")),
|
||||||
|
(
|
||||||
|
"lib.webworker.importscripts.d.ts",
|
||||||
|
inc!("lib.webworker.importscripts.d.ts"),
|
||||||
),
|
),
|
||||||
maybe_compressed_ext_lib!(
|
(
|
||||||
"lib.deno.websocket.d.ts",
|
"lib.webworker.iterable.d.ts",
|
||||||
"websocket/lib.deno_websocket.d.ts"
|
inc!("lib.webworker.iterable.d.ts"),
|
||||||
),
|
),
|
||||||
maybe_compressed_ext_lib!(
|
|
||||||
"lib.deno.webstorage.d.ts",
|
|
||||||
"webstorage/lib.deno_webstorage.d.ts"
|
|
||||||
),
|
|
||||||
maybe_compressed_ext_lib!(
|
|
||||||
"lib.deno.canvas.d.ts",
|
|
||||||
"canvas/lib.deno_canvas.d.ts"
|
|
||||||
),
|
|
||||||
maybe_compressed_ext_lib!(
|
|
||||||
"lib.deno.crypto.d.ts",
|
|
||||||
"crypto/lib.deno_crypto.d.ts"
|
|
||||||
),
|
|
||||||
maybe_compressed_ext_lib!(
|
|
||||||
"lib.deno.broadcast_channel.d.ts",
|
|
||||||
"broadcast_channel/lib.deno_broadcast_channel.d.ts"
|
|
||||||
),
|
|
||||||
maybe_compressed_ext_lib!("lib.deno.net.d.ts", "net/lib.deno_net.d.ts"),
|
|
||||||
maybe_compressed_ext_lib!(
|
|
||||||
"lib.deno.cache.d.ts",
|
|
||||||
"cache/lib.deno_cache.d.ts"
|
|
||||||
),
|
|
||||||
maybe_compressed_lib!("lib.deno.webgpu.d.ts", "lib.deno_webgpu.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.deno.window.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.deno.worker.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.deno.shared_globals.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.deno.ns.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.deno.unstable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.decorators.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.decorators.legacy.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.dom.asynciterable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.dom.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.dom.extras.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.dom.iterable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.collection.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.core.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.generator.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.iterable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.promise.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.proxy.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.reflect.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.symbol.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2015.symbol.wellknown.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2016.array.include.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2016.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2016.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2016.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.arraybuffer.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.date.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.object.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.sharedmemory.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2017.typedarrays.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.asyncgenerator.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.asynciterable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.promise.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2018.regexp.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.array.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.object.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2019.symbol.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.bigint.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.date.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.number.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.promise.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.sharedmemory.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2020.symbol.wellknown.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.promise.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2021.weakref.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.array.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.error.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.object.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.regexp.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2022.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2023.array.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2023.collection.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2023.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2023.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2023.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.arraybuffer.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.collection.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.object.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.promise.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.regexp.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.sharedmemory.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es2024.string.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es5.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.es6.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.array.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.collection.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.decorators.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.disposable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.full.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.intl.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.esnext.iterator.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.scripthost.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.webworker.asynciterable.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.webworker.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.webworker.importscripts.d.ts"),
|
|
||||||
maybe_compressed_lib!("lib.webworker.iterable.d.ts"),
|
|
||||||
(
|
(
|
||||||
// Special file that can be used to inject the @types/node package.
|
// Special file that can be used to inject the @types/node package.
|
||||||
// This is used for `node:` specifiers.
|
// This is used for `node:` specifiers.
|
||||||
"node_types.d.ts",
|
"node_types.d.ts",
|
||||||
StaticAssetSource::Uncompressed(
|
"/// <reference types=\"npm:@types/node\" />\n",
|
||||||
"/// <reference types=\"npm:@types/node\" />\n",
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -438,8 +245,8 @@ pub struct AssetText {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a static asset that are included in the binary.
|
/// Retrieve a static asset that are included in the binary.
|
||||||
fn get_lazily_loaded_asset(asset: &str) -> Option<MaybeStaticSource> {
|
fn get_lazily_loaded_asset(asset: &str) -> Option<&'static str> {
|
||||||
LAZILY_LOADED_STATIC_ASSETS.get(asset).map(|s| s.get())
|
LAZILY_LOADED_STATIC_ASSETS.get(asset).map(|s| s.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_maybe_hash(
|
fn get_maybe_hash(
|
||||||
|
@ -796,10 +603,10 @@ fn op_load_inner(
|
||||||
} else if load_specifier == MISSING_DEPENDENCY_SPECIFIER {
|
} else if load_specifier == MISSING_DEPENDENCY_SPECIFIER {
|
||||||
None
|
None
|
||||||
} else if let Some(name) = load_specifier.strip_prefix("asset:///") {
|
} else if let Some(name) = load_specifier.strip_prefix("asset:///") {
|
||||||
let maybe_source = get_lazily_loaded_asset(name).map(Cow::from);
|
let maybe_source = get_lazily_loaded_asset(name);
|
||||||
hash = get_maybe_hash(maybe_source.as_deref(), state.hash_data);
|
hash = get_maybe_hash(maybe_source, state.hash_data);
|
||||||
media_type = MediaType::from_str(load_specifier);
|
media_type = MediaType::from_str(load_specifier);
|
||||||
maybe_source
|
maybe_source.map(Cow::Borrowed)
|
||||||
} else {
|
} else {
|
||||||
let specifier = if let Some(remapped_specifier) =
|
let specifier = if let Some(remapped_specifier) =
|
||||||
state.maybe_remapped_specifier(load_specifier)
|
state.maybe_remapped_specifier(load_specifier)
|
||||||
|
@ -941,20 +748,6 @@ fn op_remap_specifier(
|
||||||
.map(|url| url.to_string())
|
.map(|url| url.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
|
||||||
#[serde]
|
|
||||||
fn op_libs() -> Vec<String> {
|
|
||||||
let mut out = Vec::with_capacity(LAZILY_LOADED_STATIC_ASSETS.len());
|
|
||||||
for key in LAZILY_LOADED_STATIC_ASSETS.keys() {
|
|
||||||
let lib = key
|
|
||||||
.replace("lib.", "")
|
|
||||||
.replace(".d.ts", "")
|
|
||||||
.replace("deno_", "deno.");
|
|
||||||
out.push(lib);
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_resolve(
|
fn op_resolve(
|
||||||
|
@ -1294,84 +1087,6 @@ pub enum ExecError {
|
||||||
Core(deno_core::error::CoreError),
|
Core(deno_core::error::CoreError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) struct CompressedSource {
|
|
||||||
bytes: &'static [u8],
|
|
||||||
uncompressed: OnceLock<Arc<str>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompressedSource {
|
|
||||||
#[cfg_attr(debug_assertions, allow(dead_code))]
|
|
||||||
pub(crate) const fn new(bytes: &'static [u8]) -> Self {
|
|
||||||
Self {
|
|
||||||
bytes,
|
|
||||||
uncompressed: OnceLock::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub(crate) fn get(&self) -> Arc<str> {
|
|
||||||
self
|
|
||||||
.uncompressed
|
|
||||||
.get_or_init(|| decompress_source(self.bytes))
|
|
||||||
.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) static MAIN_COMPILER_SOURCE: StaticAssetSource =
|
|
||||||
maybe_compressed_source!("tsc/99_main_compiler.js");
|
|
||||||
pub(crate) static LSP_SOURCE: StaticAssetSource =
|
|
||||||
maybe_compressed_source!("tsc/98_lsp.js");
|
|
||||||
pub(crate) static TS_HOST_SOURCE: StaticAssetSource =
|
|
||||||
maybe_compressed_source!("tsc/97_ts_host.js");
|
|
||||||
pub(crate) static TYPESCRIPT_SOURCE: StaticAssetSource =
|
|
||||||
maybe_compressed_source!("tsc/00_typescript.js");
|
|
||||||
|
|
||||||
pub(crate) fn decompress_source(contents: &[u8]) -> Arc<str> {
|
|
||||||
let len_bytes = contents[0..4].try_into().unwrap();
|
|
||||||
let len = u32::from_le_bytes(len_bytes);
|
|
||||||
let uncompressed =
|
|
||||||
zstd::bulk::decompress(&contents[4..], len as usize).unwrap();
|
|
||||||
String::from_utf8(uncompressed).unwrap().into()
|
|
||||||
}
|
|
||||||
|
|
||||||
deno_core::extension!(deno_cli_tsc,
|
|
||||||
ops = [
|
|
||||||
op_create_hash,
|
|
||||||
op_emit,
|
|
||||||
op_is_node_file,
|
|
||||||
op_load,
|
|
||||||
op_remap_specifier,
|
|
||||||
op_resolve,
|
|
||||||
op_respond,
|
|
||||||
op_libs,
|
|
||||||
],
|
|
||||||
options = {
|
|
||||||
request: Request,
|
|
||||||
root_map: HashMap<String, Url>,
|
|
||||||
remapped_specifiers: HashMap<String, Url>,
|
|
||||||
},
|
|
||||||
state = |state, options| {
|
|
||||||
state.put(State::new(
|
|
||||||
options.request.graph,
|
|
||||||
options.request.hash_data,
|
|
||||||
options.request.maybe_npm,
|
|
||||||
options.request.maybe_tsbuildinfo,
|
|
||||||
options.root_map,
|
|
||||||
options.remapped_specifiers,
|
|
||||||
std::env::current_dir()
|
|
||||||
.context("Unable to get CWD")
|
|
||||||
.unwrap(),
|
|
||||||
));
|
|
||||||
},
|
|
||||||
customizer = |ext: &mut deno_core::Extension| {
|
|
||||||
use deno_core::ExtensionFileSource;
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_cli_tsc/99_main_compiler.js", crate::tsc::MAIN_COMPILER_SOURCE.get().into()));
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_cli_tsc/97_ts_host.js", crate::tsc::TS_HOST_SOURCE.get().into()));
|
|
||||||
ext.esm_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_cli_tsc/98_lsp.js", crate::tsc::LSP_SOURCE.get().into()));
|
|
||||||
ext.js_files.to_mut().push(ExtensionFileSource::new_computed("ext:deno_cli_tsc/00_typescript.js", crate::tsc::TYPESCRIPT_SOURCE.get().into()));
|
|
||||||
ext.esm_entry_point = Some("ext:deno_cli_tsc/99_main_compiler.js");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Execute a request on the supplied snapshot, returning a response which
|
/// Execute a request on the supplied snapshot, returning a response which
|
||||||
/// contains information, like any emitted files, diagnostics, statistics and
|
/// contains information, like any emitted files, diagnostics, statistics and
|
||||||
/// optionally an updated TypeScript build info.
|
/// optionally an updated TypeScript build info.
|
||||||
|
@ -1402,6 +1117,36 @@ pub fn exec(request: Request) -> Result<Response, ExecError> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
deno_core::extension!(deno_cli_tsc,
|
||||||
|
ops = [
|
||||||
|
op_create_hash,
|
||||||
|
op_emit,
|
||||||
|
op_is_node_file,
|
||||||
|
op_load,
|
||||||
|
op_remap_specifier,
|
||||||
|
op_resolve,
|
||||||
|
op_respond,
|
||||||
|
],
|
||||||
|
options = {
|
||||||
|
request: Request,
|
||||||
|
root_map: HashMap<String, Url>,
|
||||||
|
remapped_specifiers: HashMap<String, Url>,
|
||||||
|
},
|
||||||
|
state = |state, options| {
|
||||||
|
state.put(State::new(
|
||||||
|
options.request.graph,
|
||||||
|
options.request.hash_data,
|
||||||
|
options.request.maybe_npm,
|
||||||
|
options.request.maybe_tsbuildinfo,
|
||||||
|
options.root_map,
|
||||||
|
options.remapped_specifiers,
|
||||||
|
std::env::current_dir()
|
||||||
|
.context("Unable to get CWD")
|
||||||
|
.unwrap(),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let request_value = json!({
|
let request_value = json!({
|
||||||
"config": request.config,
|
"config": request.config,
|
||||||
"debug": request.debug,
|
"debug": request.debug,
|
||||||
|
@ -1411,7 +1156,8 @@ pub fn exec(request: Request) -> Result<Response, ExecError> {
|
||||||
let exec_source = format!("globalThis.exec({request_value})");
|
let exec_source = format!("globalThis.exec({request_value})");
|
||||||
|
|
||||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||||
extensions: vec![deno_cli_tsc::init_ops_and_esm(
|
startup_snapshot: Some(compiler_snapshot()),
|
||||||
|
extensions: vec![deno_cli_tsc::init_ops(
|
||||||
request,
|
request,
|
||||||
root_map,
|
root_map,
|
||||||
remapped_specifiers,
|
remapped_specifiers,
|
||||||
|
@ -1573,21 +1319,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_compiler_snapshot() {
|
async fn test_compiler_snapshot() {
|
||||||
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
startup_snapshot: None,
|
startup_snapshot: Some(compiler_snapshot()),
|
||||||
extensions: vec![super::deno_cli_tsc::init_ops_and_esm(
|
|
||||||
Request {
|
|
||||||
check_mode: TypeCheckMode::All,
|
|
||||||
config: Arc::new(TsConfig(json!({}))),
|
|
||||||
debug: false,
|
|
||||||
graph: Arc::new(ModuleGraph::new(GraphKind::TypesOnly)),
|
|
||||||
hash_data: 0,
|
|
||||||
maybe_npm: None,
|
|
||||||
maybe_tsbuildinfo: None,
|
|
||||||
root_names: vec![],
|
|
||||||
},
|
|
||||||
HashMap::new(),
|
|
||||||
HashMap::new(),
|
|
||||||
)],
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
js_runtime
|
js_runtime
|
||||||
|
@ -1670,7 +1402,7 @@ mod tests {
|
||||||
.expect("should have invoked op")
|
.expect("should have invoked op")
|
||||||
.expect("load should have succeeded");
|
.expect("load should have succeeded");
|
||||||
let expected = get_lazily_loaded_asset("lib.dom.d.ts").unwrap();
|
let expected = get_lazily_loaded_asset("lib.dom.d.ts").unwrap();
|
||||||
assert_eq!(actual.data, expected.to_string());
|
assert_eq!(actual.data, expected);
|
||||||
assert!(actual.version.is_some());
|
assert!(actual.version.is_some());
|
||||||
assert_eq!(actual.script_kind, 3);
|
assert_eq!(actual.script_kind, 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11612,12 +11612,14 @@ fn lsp_performance() {
|
||||||
"lsp.update_diagnostics_lint",
|
"lsp.update_diagnostics_lint",
|
||||||
"lsp.update_diagnostics_ts",
|
"lsp.update_diagnostics_ts",
|
||||||
"lsp.update_global_cache",
|
"lsp.update_global_cache",
|
||||||
|
"tsc.host.$getAssets",
|
||||||
"tsc.host.$getDiagnostics",
|
"tsc.host.$getDiagnostics",
|
||||||
"tsc.host.$getSupportedCodeFixes",
|
"tsc.host.$getSupportedCodeFixes",
|
||||||
"tsc.host.getQuickInfoAtPosition",
|
"tsc.host.getQuickInfoAtPosition",
|
||||||
"tsc.op.op_is_node_file",
|
"tsc.op.op_is_node_file",
|
||||||
"tsc.op.op_load",
|
"tsc.op.op_load",
|
||||||
"tsc.op.op_script_names",
|
"tsc.op.op_script_names",
|
||||||
|
"tsc.request.$getAssets",
|
||||||
"tsc.request.$getDiagnostics",
|
"tsc.request.$getDiagnostics",
|
||||||
"tsc.request.$getSupportedCodeFixes",
|
"tsc.request.$getSupportedCodeFixes",
|
||||||
"tsc.request.getQuickInfoAtPosition",
|
"tsc.request.getQuickInfoAtPosition",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue