Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions crates/next-core/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::future::Future;
use std::{future::Future, str::FromStr};

use anyhow::{Context, Result, bail};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
Expand Down Expand Up @@ -60,13 +60,10 @@ pub fn defines(define_env: &FxIndexMap<RcStr, Option<RcStr>>) -> CompileTimeDefi
)
.or_insert_with(|| {
if let Some(v) = v {
let val = serde_json::from_str(v);
let val = serde_json::Value::from_str(v);
match val {
Ok(serde_json::Value::Bool(v)) => CompileTimeDefineValue::Bool(v),
Ok(serde_json::Value::String(v)) => {
CompileTimeDefineValue::String(v.into())
}
_ => CompileTimeDefineValue::JSON(v.clone()),
Ok(v) => v.into(),
_ => CompileTimeDefineValue::Evaluate(v.clone()),
}
} else {
CompileTimeDefineValue::Undefined
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/build/swc/generated-native.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function lightningCssTransformStyleAttribute(

/* auto-generated by NAPI-RS */

export declare class ExternalObject<T> {
export class ExternalObject<T> {
readonly '': {
readonly '': unique symbol
[K: symbol]: T
Expand Down
6 changes: 6 additions & 0 deletions turbopack/crates/turbo-rcstr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ impl AsRef<[u8]> for RcStr {
}
}

impl From<RcStr> for BytesStr {
fn from(value: RcStr) -> Self {
Self::from_str_slice(value.as_str())
}
}

impl PartialEq<str> for RcStr {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
Expand Down
9 changes: 7 additions & 2 deletions turbopack/crates/turbo-tasks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,20 @@ futures = { workspace = true }
indexmap = { workspace = true, features = ["serde"] }
mopa = "0.2.0"
once_cell = { workspace = true }
parking_lot = { workspace = true, features = ["serde"]}
parking_lot = { workspace = true, features = ["serde"] }
pin-project-lite = { workspace = true }
rayon = { workspace = true }
regex = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true, features = ["rc", "derive"] }
serde_json = { workspace = true }
serde_regex = "1.1.0"
shrink-to-fit = { workspace=true,features = ["indexmap", "serde_json", "smallvec", "nightly"] }
shrink-to-fit = { workspace = true, features = [
"indexmap",
"serde_json",
"smallvec",
"nightly",
] }
smallvec = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
Expand Down
2 changes: 1 addition & 1 deletion turbopack/crates/turbo-tasks/src/task/task_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ where
async fn resolve_input(&self) -> Result<Self> {
let mut resolved = Vec::with_capacity(self.len());
for value in self {
resolved.push(value.resolve_input().await?);
resolved.push(Box::pin(value.resolve_input()).await?);
}
Ok(resolved)
}
Expand Down
17 changes: 15 additions & 2 deletions turbopack/crates/turbopack-core/src/compile_time_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ macro_rules! free_var_references {
#[turbo_tasks::value]
#[derive(Debug, Clone, Hash, TaskInput)]
pub enum CompileTimeDefineValue {
Null,
Bool(bool),
Number(RcStr),
String(RcStr),
JSON(RcStr),
Array(Vec<CompileTimeDefineValue>),
Object(Vec<(RcStr, CompileTimeDefineValue)>),
Undefined,
Evaluate(RcStr),
}

impl From<bool> for CompileTimeDefineValue {
Expand Down Expand Up @@ -136,7 +140,16 @@ impl From<&str> for CompileTimeDefineValue {

impl From<serde_json::Value> for CompileTimeDefineValue {
fn from(value: serde_json::Value) -> Self {
Self::JSON(value.to_string().into())
match value {
serde_json::Value::Null => Self::Null,
serde_json::Value::Bool(b) => Self::Bool(b),
serde_json::Value::Number(n) => Self::Number(n.to_string().into()),
serde_json::Value::String(s) => Self::String(s.into()),
serde_json::Value::Array(a) => Self::Array(a.into_iter().map(|i| i.into()).collect()),
serde_json::Value::Object(m) => {
Self::Object(m.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
}
}
}

Expand Down
55 changes: 54 additions & 1 deletion turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ use std::{
sync::Arc,
};

use anyhow::{Ok, Result, bail};
use rustc_hash::{FxHashMap, FxHashSet};
use swc_core::{
atoms::Atom,
common::{GLOBALS, Mark, Span, Spanned, SyntaxContext, comments::Comments, pass::AstNodePath},
base::try_with_handler,
common::{
FileName, GLOBALS, Mark, SourceMap, Span, Spanned, SyntaxContext, comments::Comments,
pass::AstNodePath, sync::Lrc,
},
ecma::{
ast::*,
atoms::atom,
parser::{Syntax, parse_file_as_program},
utils::contains_ident_ref,
visit::{fields::*, *},
},
Expand Down Expand Up @@ -720,6 +726,53 @@ impl EvalContext {
_ => JsValue::unknown_empty(true, "unsupported expression"),
}
}

pub fn eval_single_expr_lit(expr_lit: RcStr) -> Result<JsValue> {
let cm = Lrc::new(SourceMap::default());
let fm = cm.new_source_file(FileName::Anon.into(), expr_lit.clone());

let js_value = try_with_handler(cm, Default::default(), |handler| {
GLOBALS.set(&Default::default(), || {
let program = parse_file_as_program(
&fm,
Syntax::Es(Default::default()),
EsVersion::latest(),
None,
&mut vec![],
)
.map_or_else(
|e| {
e.into_diagnostic(handler).emit();
bail!(r#"Failed to evaluate compile-time defined value expression: "{expr_lit}""#)
},
Ok,
)?;

let eval_context = EvalContext::new(
&program,
Mark::new(),Mark::new(),
Default::default(),
None,
None,
);

if let Program::Script(script) = program {
if script.body.len() == 1
&& let Some(Stmt::Expr(expr_stmt)) = script.body.first()
{
Ok(eval_context.eval(&expr_stmt.expr))
} else {
bail!(r#"Failed to parse compile-time defined value expression: "{expr_lit}""#)
}
} else {
bail!(r#"Failed to parse compile-time defined value: "{expr_lit}" in non-script context"#)
}
})
})
.map_err(|e| e.to_pretty_error())?;

Ok(js_value)
}
}

enum EarlyReturn {
Expand Down
88 changes: 63 additions & 25 deletions turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ use turbopack_core::compile_time_info::{

use self::imports::ImportAnnotations;
pub(crate) use self::imports::ImportMap;
use crate::{references::require_context::RequireContextMap, utils::StringifyJs};
use crate::{
analyzer::graph::EvalContext, references::require_context::RequireContextMap,
utils::StringifyJs,
};

pub mod builtin;
pub mod graph;
Expand Down Expand Up @@ -581,38 +584,73 @@ impl From<ConstantValue> for JsValue {
}
}

impl From<&CompileTimeDefineValue> for JsValue {
fn from(v: &CompileTimeDefineValue) -> Self {
match v {
CompileTimeDefineValue::String(s) => JsValue::Constant(s.as_str().into()),
CompileTimeDefineValue::Bool(b) => JsValue::Constant((*b).into()),
CompileTimeDefineValue::JSON(_) => {
JsValue::unknown_empty(false, "compile time injected JSON")
impl TryFrom<&CompileTimeDefineValue> for JsValue {
type Error = anyhow::Error;

fn try_from(value: &CompileTimeDefineValue) -> Result<Self> {
match value {
CompileTimeDefineValue::Null => Ok(JsValue::Constant(ConstantValue::Null)),
CompileTimeDefineValue::Bool(b) => Ok(JsValue::Constant((*b).into())),
CompileTimeDefineValue::Number(n) => Ok(JsValue::Constant(ConstantValue::Num(
ConstantNumber(n.as_str().parse::<f64>()?),
))),
CompileTimeDefineValue::String(s) => Ok(JsValue::Constant(s.as_str().into())),
CompileTimeDefineValue::Array(a) => {
let mut js_value = JsValue::Array {
total_nodes: a.len() as u32,
items: a.iter().map(|i| i.try_into()).try_collect()?,
mutable: false,
};
js_value.update_total_nodes();
Ok(js_value)
}
CompileTimeDefineValue::Undefined => JsValue::Constant(ConstantValue::Undefined),
CompileTimeDefineValue::Object(m) => {
let mut js_value = JsValue::Object {
total_nodes: m.len() as u32,
parts: m
.iter()
.map(|(k, v)| {
Ok::<ObjectPart, anyhow::Error>(ObjectPart::KeyValue(
k.clone().into(),
v.try_into()?,
))
})
.try_collect()?,
mutable: false,
};
js_value.update_total_nodes();
Ok(js_value)
}
CompileTimeDefineValue::Undefined => Ok(JsValue::Constant(ConstantValue::Undefined)),
CompileTimeDefineValue::Evaluate(s) => EvalContext::eval_single_expr_lit(s.clone()),
}
}
}

impl From<&FreeVarReference> for JsValue {
fn from(v: &FreeVarReference) -> Self {
match v {
FreeVarReference::Value(v) => v.into(),
impl TryFrom<&FreeVarReference> for JsValue {
type Error = anyhow::Error;

fn try_from(value: &FreeVarReference) -> Result<Self> {
match value {
FreeVarReference::Value(v) => v.try_into(),
FreeVarReference::Ident(_) => {
JsValue::unknown_empty(false, "compile time injected ident")
}
FreeVarReference::Member(_, _) => {
JsValue::unknown_empty(false, "compile time injected member")
}
FreeVarReference::EcmaScriptModule { .. } => {
JsValue::unknown_empty(false, "compile time injected free var module")
}
FreeVarReference::Error(_) => {
JsValue::unknown_empty(false, "compile time injected free var error")
Ok(JsValue::unknown_empty(false, "compile time injected ident"))
}
FreeVarReference::Member(_, _) => Ok(JsValue::unknown_empty(
false,
"compile time injected member",
)),
FreeVarReference::EcmaScriptModule { .. } => Ok(JsValue::unknown_empty(
false,
"compile time injected free var module",
)),
FreeVarReference::Error(_) => Ok(JsValue::unknown_empty(
false,
"compile time injected free var error",
)),
FreeVarReference::InputRelative(kind) => {
use turbopack_core::compile_time_info::InputRelativeConstant;
JsValue::unknown_empty(
Ok(JsValue::unknown_empty(
false,
match kind {
InputRelativeConstant::DirName => {
Expand All @@ -622,7 +660,7 @@ impl From<&FreeVarReference> for JsValue {
"compile time injected free var referencing the file name"
}
},
)
))
}
}
}
Expand Down
1 change: 1 addition & 0 deletions turbopack/crates/turbopack-ecmascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(int_roundings)]
#![feature(arbitrary_self_types)]
#![feature(arbitrary_self_types_pointers)]
#![feature(iterator_try_collect)]
#![recursion_limit = "256"]

pub mod analyzer;
Expand Down
Loading
Loading