From 15ab9f40ad31f64bb2ce508b4e479e6268b6db3b Mon Sep 17 00:00:00 2001 From: hrmny Date: Thu, 21 Sep 2023 23:42:28 +0200 Subject: [PATCH] fix free var replacements (compile time defines) and allow JSON values --- .../turbopack-core/src/compile_time_info.rs | 12 ++++++++- .../turbopack-ecmascript/src/analyzer/mod.rs | 1 + .../turbopack-ecmascript/src/path_visitor.rs | 1 + .../src/references/constant_value.rs | 25 +++++++++++-------- crates/turbopack-tests/tests/snapshot.rs | 23 +++++++++-------- .../snapshot/comptime/define/input/index.js | 1 - ...shot_comptime_define_input_index_b53fce.js | 15 ++++++----- ..._comptime_define_input_index_b53fce.js.map | 4 +-- 8 files changed, 49 insertions(+), 33 deletions(-) diff --git a/crates/turbopack-core/src/compile_time_info.rs b/crates/turbopack-core/src/compile_time_info.rs index a98c7b9d96e58..1e4773aca5448 100644 --- a/crates/turbopack-core/src/compile_time_info.rs +++ b/crates/turbopack-core/src/compile_time_info.rs @@ -77,6 +77,7 @@ macro_rules! free_var_references { pub enum CompileTimeDefineValue { Bool(bool), String(String), + JSON(String), } impl From for CompileTimeDefineValue { @@ -97,7 +98,14 @@ impl From<&str> for CompileTimeDefineValue { } } +impl From for CompileTimeDefineValue { + fn from(value: serde_json::Value) -> Self { + Self::JSON(value.to_string()) + } +} + #[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] pub struct CompileTimeDefines(pub IndexMap, CompileTimeDefineValue>); impl IntoIterator for CompileTimeDefines { @@ -118,7 +126,7 @@ impl CompileTimeDefines { } #[turbo_tasks::value] -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum FreeVarReference { EcmaScriptModule { request: String, @@ -153,6 +161,7 @@ impl From for FreeVarReference { } #[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] pub struct FreeVarReferences(pub IndexMap, FreeVarReference>); #[turbo_tasks::value_impl] @@ -164,6 +173,7 @@ impl FreeVarReferences { } #[turbo_tasks::value(shared)] +#[derive(Debug, Clone)] pub struct CompileTimeInfo { pub environment: Vc, pub defines: Vc, diff --git a/crates/turbopack-ecmascript/src/analyzer/mod.rs b/crates/turbopack-ecmascript/src/analyzer/mod.rs index 2efe8ca6dfee9..c7f327cc9310b 100644 --- a/crates/turbopack-ecmascript/src/analyzer/mod.rs +++ b/crates/turbopack-ecmascript/src/analyzer/mod.rs @@ -502,6 +502,7 @@ impl From<&CompileTimeDefineValue> for JsValue { match v { CompileTimeDefineValue::String(s) => JsValue::Constant(s.as_str().into()), CompileTimeDefineValue::Bool(b) => JsValue::Constant((*b).into()), + CompileTimeDefineValue::JSON(_) => JsValue::unknown_empty("compile time injected JSON"), } } } diff --git a/crates/turbopack-ecmascript/src/path_visitor.rs b/crates/turbopack-ecmascript/src/path_visitor.rs index 7d543dabea6b9..f5b30a0068312 100644 --- a/crates/turbopack-ecmascript/src/path_visitor.rs +++ b/crates/turbopack-ecmascript/src/path_visitor.rs @@ -144,6 +144,7 @@ impl VisitMutAstPath for ApplyVisitors<'_, '_> { // TODO: we need a macro to apply that for all methods method!(visit_mut_prop, Prop); method!(visit_mut_expr, Expr); + method!(visit_mut_member_expr, MemberExpr); method!(visit_mut_pat, Pat); method!(visit_mut_stmt, Stmt); method!(visit_mut_module_decl, ModuleDecl); diff --git a/crates/turbopack-ecmascript/src/references/constant_value.rs b/crates/turbopack-ecmascript/src/references/constant_value.rs index 762260d19d25f..dc93b573b3a4e 100644 --- a/crates/turbopack-ecmascript/src/references/constant_value.rs +++ b/crates/turbopack-ecmascript/src/references/constant_value.rs @@ -35,17 +35,20 @@ impl CodeGenerateable for ConstantValue { _context: Vc>, ) -> Result> { let value = self.value.clone(); - let visitors = [ - create_visitor!(exact &self.path.await?, visit_mut_expr(expr: &mut Expr) { - *expr = match value { - CompileTimeDefineValue::Bool(true) => quote!("(\"TURBOPACK compile-time value\", true)" as Expr), - CompileTimeDefineValue::Bool(false) => quote!("(\"TURBOPACK compile-time value\", false)" as Expr), - CompileTimeDefineValue::String(ref s) => quote!("(\"TURBOPACK compile-time value\", $e)" as Expr, e: Expr = s.to_string().into()), - }; - }), - ] - .into(); + let path = &self.path.await?; - Ok(CodeGeneration { visitors }.cell()) + let visitor = create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = match value { + CompileTimeDefineValue::Bool(true) => quote!("(\"TURBOPACK compile-time value\", true)" as Expr), + CompileTimeDefineValue::Bool(false) => quote!("(\"TURBOPACK compile-time value\", false)" as Expr), + CompileTimeDefineValue::String(ref s) => quote!("(\"TURBOPACK compile-time value\", $e)" as Expr, e: Expr = s.to_string().into()), + CompileTimeDefineValue::JSON(ref s) => quote!("(\"TURBOPACK compile-time value\", JSON.parse($e))" as Expr, e: Expr = s.to_string().into()), + }; + }); + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .cell()) } } diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index cc4e96ea10ae6..0e3ee5ae34fc4 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -11,6 +11,7 @@ use std::{ use anyhow::{bail, Context, Result}; use dunce::canonicalize; use serde::Deserialize; +use serde_json::json; use turbo_tasks::{ReadRef, TryJoinIterExt, TurboTasks, Value, ValueToString, Vc}; use turbo_tasks_env::DotenvProcessEnv; use turbo_tasks_fs::{ @@ -34,6 +35,7 @@ use turbopack_core::{ context::AssetContext, environment::{BrowserEnvironment, Environment, ExecutionEnvironment, NodeJsEnvironment}, file_source::FileSource, + free_var_references, issue::{Issue, IssueDescriptionExt}, module::Module, output::OutputAsset, @@ -209,17 +211,18 @@ async fn run_test(resource: String) -> Result> { ) } })); + + let defines = compile_time_defines!( + process.turbopack = true, + process.env.NODE_ENV = "development", + DEFINED_VALUE = "value", + DEFINED_TRUE = true, + A.VERY.LONG.DEFINED.VALUE = json!({ "test": true }), + ); + let compile_time_info = CompileTimeInfo::builder(env) - .defines( - compile_time_defines!( - process.turbopack = true, - process.env.NODE_ENV = "development", - DEFINED_VALUE = "value", - DEFINED_TRUE = true, - A.VERY.LONG.DEFINED.VALUE = "value", - ) - .cell(), - ) + .defines(defines.clone().cell()) + .free_var_references(free_var_references!(..defines.into_iter()).cell()) .cell(); let custom_ecma_transform_plugins = Some(CustomEcmascriptTransformPlugins::cell( diff --git a/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js b/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js index a7db47e163820..d3bdb3f0bf7f2 100644 --- a/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js +++ b/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js @@ -20,7 +20,6 @@ if (process.env.NODE_ENV === 'production') { var p = process; -// TODO: replacement is not implemented yet console.log(A.VERY.LONG.DEFINED.VALUE); console.log(DEFINED_VALUE); console.log(p.env.NODE_ENV); diff --git a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js index f0cb926b01a0a..bbd1b3eb62feb 100644 --- a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js +++ b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js @@ -8,7 +8,7 @@ if ("TURBOPACK compile-time truthy", 1) { if ("TURBOPACK compile-time truthy", 1) { console.log('DEFINED_VALUE'); } -if ("TURBOPACK compile-time truthy", 1) { +if ("TURBOPACK compile-time value", JSON.parse('{"test":true}')) { console.log('A.VERY.LONG.DEFINED.VALUE'); } if ("TURBOPACK compile-time truthy", 1) { @@ -18,19 +18,18 @@ if ("TURBOPACK compile-time falsy", 0) { "TURBOPACK unreachable"; } var p = process; -// TODO: replacement is not implemented yet -console.log(A.VERY.LONG.DEFINED.VALUE); -console.log(DEFINED_VALUE); -console.log(p.env.NODE_ENV); +console.log(("TURBOPACK compile-time value", JSON.parse('{"test":true}'))); +console.log(("TURBOPACK compile-time value", "value")); +console.log(("TURBOPACK compile-time value", "development")); if ("TURBOPACK compile-time falsy", 0) { "TURBOPACK unreachable"; } ("TURBOPACK compile-time falsy", 0) ? ("TURBOPACK unreachable", undefined) : console.log('development'); // TODO short-circuit is not implemented yet -p.env.NODE_ENV != 'production' && console.log('development'); -p.env.NODE_ENV == 'production' && console.log('production'); +("TURBOPACK compile-time value", "development") != 'production' && console.log('development'); +("TURBOPACK compile-time value", "development") == 'production' && console.log('production'); }.call(this) }), }]); -//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map index 29e82b4dfa332..e9d7f148a178f 100644 --- a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map +++ b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map @@ -1,6 +1,6 @@ { "version": 3, "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js"],"sourcesContent":["if (DEFINED_VALUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (DEFINED_TRUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (A.VERY.LONG.DEFINED.VALUE) {\n console.log('A.VERY.LONG.DEFINED.VALUE');\n}\n\nif (process.env.NODE_ENV) {\n console.log('something');\n}\n\nif (process.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\nvar p = process;\n\n// TODO: replacement is not implemented yet\nconsole.log(A.VERY.LONG.DEFINED.VALUE);\nconsole.log(DEFINED_VALUE);\nconsole.log(p.env.NODE_ENV);\n\nif (p.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\np.env.NODE_ENV == 'production' ? console.log('production') : console.log('development');\n\n// TODO short-circuit is not implemented yet\np.env.NODE_ENV != 'production' && console.log('development');\np.env.NODE_ENV == 'production' && console.log('production');\n"],"names":[],"mappings":"AAAA,wCAAmB;IACjB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAAkB;IAChB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA+B;IAC7B,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA0B;IACxB,QAAQ,GAAG,CAAC;AACd;AAEA;;;AAIA,IAAI,IAAI;AAER,2CAA2C;AAC3C,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK;AACrC,QAAQ,GAAG,CAAC;AACZ,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,QAAQ;AAE1B;;;AAIA,6EAA6D,QAAQ,GAAG,CAAC;AAEzE,4CAA4C;AAC5C,EAAE,GAAG,CAAC,QAAQ,IAAI,gBAAgB,QAAQ,GAAG,CAAC;AAC9C,EAAE,GAAG,CAAC,QAAQ,IAAI,gBAAgB,QAAQ,GAAG,CAAC"}}, - {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js"],"sourcesContent":["if (DEFINED_VALUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (DEFINED_TRUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (A.VERY.LONG.DEFINED.VALUE) {\n console.log('A.VERY.LONG.DEFINED.VALUE');\n}\n\nif (process.env.NODE_ENV) {\n console.log('something');\n}\n\nif (process.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\nvar p = process;\n\nconsole.log(A.VERY.LONG.DEFINED.VALUE);\nconsole.log(DEFINED_VALUE);\nconsole.log(p.env.NODE_ENV);\n\nif (p.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\np.env.NODE_ENV == 'production' ? console.log('production') : console.log('development');\n\n// TODO short-circuit is not implemented yet\np.env.NODE_ENV != 'production' && console.log('development');\np.env.NODE_ENV == 'production' && console.log('production');\n"],"names":[],"mappings":"AAAA,wCAAmB;IACjB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAAkB;IAChB,QAAQ,GAAG,CAAC;AACd;AAEA,iEAA+B;IAC7B,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA0B;IACxB,QAAQ,GAAG,CAAC;AACd;AAEA;;;AAIA,IAAI,IAAI;AAER,QAAQ,GAAG;AACX,QAAQ,GAAG;AACX,QAAQ,GAAG;AAEX;;;AAIA,6EAA6D,QAAQ,GAAG,CAAC;AAEzE,4CAA4C;AAC5C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC;AAC9C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 30, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file