diff --git a/Cargo.lock b/Cargo.lock index f349ba0326..eb8becddc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,7 +183,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -254,6 +254,20 @@ dependencies = [ [[package]] name = "binding_wasm" version = "0.1.0" +dependencies = [ + "anyhow", + "serde", + "serde-wasm-bindgen", + "stc_ts_env", + "stc_ts_errors", + "stc_ts_file_analyzer", + "stc_ts_type_checker", + "swc_common", + "swc_ecma_ast", + "swc_ecma_loader", + "swc_ecma_parser", + "wasm-bindgen", +] [[package]] name = "bitflags" @@ -361,7 +375,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -506,12 +520,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "darling" version = "0.13.4" @@ -693,12 +701,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -761,7 +763,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -1295,26 +1297,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "mimalloc-rust" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb726c8298efb4010b2c46d8050e4be36cf807b9d9e98cb112f830914fc9bbe" -dependencies = [ - "cty", - "mimalloc-rust-sys", -] - -[[package]] -name = "mimalloc-rust-sys" -version = "1.7.9-source" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413e13241a9809f291568133eca6694572cf528c1a6175502d090adce5dd5db" -dependencies = [ - "cc", - "cty", -] - [[package]] name = "miniz_oxide" version = "0.6.2" @@ -1596,7 +1578,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -2007,29 +1989,40 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -2044,7 +2037,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -2173,7 +2166,6 @@ dependencies = [ "swc_common", "swc_ecma_ast", "swc_ecma_parser", - "swc_node_base", "tokio", "tracing", "tracing-subscriber 0.2.25", @@ -2741,7 +2733,6 @@ dependencies = [ "rustc-hash", "scoped-tls", "swc_common", - "swc_node_base", "tracing", ] @@ -3099,16 +3090,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "swc_node_base" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6065892f97ac3f42280d0f3eadc351aeff552e8de4d459604bcd9c56eb799ade" -dependencies = [ - "mimalloc-rust", - "tikv-jemallocator", -] - [[package]] name = "swc_visit" version = "0.5.6" @@ -3146,9 +3127,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", @@ -3248,7 +3229,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -3283,27 +3264,6 @@ dependencies = [ "threadpool", ] -[[package]] -name = "tikv-jemalloc-sys" -version = "0.4.3+5.2.1-patched.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1792ccb507d955b46af42c123ea8863668fae24d03721e40cad6a41773dbb49" -dependencies = [ - "cc", - "fs_extra", - "libc", -] - -[[package]] -name = "tikv-jemallocator" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b7bcecfafe4998587d636f9ae9d55eb9d0499877b88757767c346875067098" -dependencies = [ - "libc", - "tikv-jemalloc-sys", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -3353,7 +3313,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -3450,7 +3410,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", ] [[package]] @@ -3663,34 +3623,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", + "serde", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3698,22 +3659,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.31", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "winapi" diff --git a/crates/binding_wasm/Cargo.toml b/crates/binding_wasm/Cargo.toml index c1aad7e3bd..0a8c6835e1 100644 --- a/crates/binding_wasm/Cargo.toml +++ b/crates/binding_wasm/Cargo.toml @@ -8,3 +8,15 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [dependencies] +anyhow = "1" +serde = { version = "1.0", features = ["derive"] } +serde-wasm-bindgen = "0.5" +wasm-bindgen = { version = "0.2.87", features = ["serde"] } +stc_ts_env = { path = "../stc_ts_env" } +stc_ts_errors = { path = "../stc_ts_errors" } +stc_ts_file_analyzer = { path = "../stc_ts_file_analyzer" } +stc_ts_type_checker = { path = "../stc_ts_type_checker" } +swc_common = { version = "0.29.37", features = ["tty-emitter"] } +swc_ecma_ast = "0.100.2" +swc_ecma_loader = "0.41.39" +swc_ecma_parser = "0.130.5" diff --git a/crates/binding_wasm/src/lib.rs b/crates/binding_wasm/src/lib.rs index 7d12d9af81..66a2832861 100644 --- a/crates/binding_wasm/src/lib.rs +++ b/crates/binding_wasm/src/lib.rs @@ -1,14 +1,147 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +use std::{ + path::PathBuf, + str::FromStr, + sync::{Arc, Mutex}, +}; + +use anyhow::{anyhow, Result}; +use serde::{Deserialize, Serialize}; +use stc_ts_env::{BuiltIn, Env, ModuleConfig, Rule, StableEnv}; +use stc_ts_type_checker::{ + loader::{LoadFile, ModuleLoader}, + Checker, +}; +use swc_common::{ + errors::{EmitterWriter, Handler}, + FileName, Globals, SourceFile, SourceMap, GLOBALS, +}; +use swc_ecma_ast::EsVersion; +use swc_ecma_loader::resolve::Resolve; +use swc_ecma_parser::Syntax; + +const ENTRY_FILENAME: &str = "binding-wasm-entry-module"; + +#[cfg(target_arch = "wasm32")] +type Out = wasm_bindgen::JsValue; +#[cfg(not(target_arch = "wasm32"))] +type Out = CheckAndAnnotateOutput; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen)] +pub fn check_and_annotate_types(src: &str) -> Out { + let globals = Arc::::default(); + let cm = Arc::new(SourceMap::default()); + let buf = Arc::new(Mutex::new(Vec::new())); + let env = GLOBALS.set(&globals, || { + Env::new( + StableEnv::new(), + Rule { ..Default::default() }, + EsVersion::latest(), + ModuleConfig::None, + Arc::new(BuiltIn::default()), + ) + }); + let emitter = Box::new(EmitterWriter::new( + Box::new(PassThroughWriter { buf: buf.clone() }), + Some(cm.clone()), + false, + false, + )); + let handler = { Arc::new(Handler::with_emitter(true, false, emitter)) }; + let (types, errors) = GLOBALS.set(&globals, || { + let loader = SingleEntryLoader::new(cm.as_ref(), src); + let mut checker = Checker::new( + cm.clone(), + handler.clone(), + env.clone(), + None, + Box::new(ModuleLoader::new(cm, env, VoidResolver, loader)), + ); + + let entry_module = checker.check(Arc::new(FileName::Real(PathBuf::from_str(ENTRY_FILENAME).unwrap()))); + let types = checker.get_types(entry_module); + + (types, checker.take_errors()) + }); + let _types = types.map(|types| format!("{:?}", types)).unwrap_or_else(|| "".to_owned()); + + for err in &errors { + err.emit(&handler); + } + + let out = CheckAndAnnotateOutput { + error: String::from_utf8_lossy(&buf.lock().unwrap()).into_owned(), + }; + + #[cfg(target_arch = "wasm32")] + { + serde_wasm_bindgen::to_value(&out).unwrap() + } + + #[cfg(not(target_arch = "wasm32"))] + { + out + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CheckAndAnnotateOutput { + error: String, +} + +pub struct PassThroughWriter { + pub buf: Arc>>, +} + +impl std::io::Write for PassThroughWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.buf.lock().unwrap().write(buf) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.buf.lock().unwrap().flush() + } +} + +pub struct VoidResolver; + +impl Resolve for VoidResolver { + fn resolve(&self, base: &FileName, _module_specifier: &str) -> std::result::Result { + if base != &FileName::Real(PathBuf::from_str(ENTRY_FILENAME).unwrap()) { + return Err(anyhow!("you cannot load any module")); + } + + Ok(base.clone()) + } +} + +pub struct SingleEntryLoader { + src: Arc, +} + +impl SingleEntryLoader { + pub fn new(source_map: &SourceMap, source: impl Into) -> Self { + Self { + src: source_map.new_source_file(FileName::Real(PathBuf::from_str(ENTRY_FILENAME).unwrap()), source.into()), + } + } +} + +impl LoadFile for SingleEntryLoader { + fn load_file(&self, _cm: &Arc, filename: &Arc) -> Result<(Arc, Syntax)> { + if filename.as_ref() != &FileName::Real(PathBuf::from_str(ENTRY_FILENAME).unwrap()) { + return Err(anyhow!("you cannot load any file")); + } + + Ok((self.src.clone(), Syntax::Typescript(Default::default()))) + } } #[cfg(test)] -mod tests { +mod test { use super::*; #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); + fn it_should_be_called() { + println!("Error: {:#?}", check_and_annotate_types("export const a: string = 1;")); } } diff --git a/crates/stc/Cargo.toml b/crates/stc/Cargo.toml index 79bcc61f63..e5ce3264c0 100644 --- a/crates/stc/Cargo.toml +++ b/crates/stc/Cargo.toml @@ -28,7 +28,6 @@ stc_utils = { path = "../stc_utils" } swc_common = { version = "0.29.37", features = ["tty-emitter"] } swc_ecma_ast = "0.100.2" swc_ecma_parser = "0.130.5" -swc_node_base = "0.5.8" tokio = { version = "1.7.1", features = ["rt-multi-thread", "macros"] } tracing = { version = "0.1.37", features = ["release_max_level_off"] } tracing-subscriber = { version = "0.2.19", features = ["env-filter"] } diff --git a/crates/stc/src/main.rs b/crates/stc/src/main.rs index 0c026628d4..ee566792ed 100644 --- a/crates/stc/src/main.rs +++ b/crates/stc/src/main.rs @@ -1,5 +1,3 @@ -extern crate swc_node_base; - use std::{path::PathBuf, sync::Arc}; use anyhow::Error; diff --git a/crates/stc_ts_file_analyzer/src/env.rs b/crates/stc_ts_file_analyzer/src/env.rs index 5eeb37889f..4f42befd17 100644 --- a/crates/stc_ts_file_analyzer/src/env.rs +++ b/crates/stc_ts_file_analyzer/src/env.rs @@ -1,5 +1,6 @@ use std::{collections::hash_map::Entry, error::Error, path::Path, sync::Arc}; +// use std::time::Instant; use dashmap::DashMap; use once_cell::sync::{Lazy, OnceCell}; use rnode::{NodeIdGenerator, RNode, VisitWith}; diff --git a/crates/stc_utils/Cargo.toml b/crates/stc_utils/Cargo.toml index b2d311be79..2c5f013ac1 100644 --- a/crates/stc_utils/Cargo.toml +++ b/crates/stc_utils/Cargo.toml @@ -14,5 +14,4 @@ once_cell = "1" rustc-hash = "1.1.0" scoped-tls = "1.0.0" swc_common = { version = "0.29.37", features = ["concurrent", "tty-emitter"] } -swc_node_base = "0.5.8" tracing = "0.1.37" diff --git a/crates/stc_utils/src/lib.rs b/crates/stc_utils/src/lib.rs index d8436846c0..4f3c6d818d 100644 --- a/crates/stc_utils/src/lib.rs +++ b/crates/stc_utils/src/lib.rs @@ -1,8 +1,5 @@ #![feature(never_type)] -/// Use good memory allocator. -extern crate swc_node_base; - use std::{ collections::{HashMap, HashSet}, env, fmt, diff --git a/cspell.json b/cspell.json index 0b9c4d6769..72dd8d7e69 100644 --- a/cspell.json +++ b/cspell.json @@ -3,6 +3,7 @@ "ahash", "arity", "autocrlf", + "bindgen", "bitflags", "bitor", "bivariant", @@ -125,4 +126,4 @@ "scripts/npm", "**/stc_ts_testing/src/conformance.rs" ] -} \ No newline at end of file +}