Skip to main content

turbopack_ecmascript/analyzer/jsvalue/
display.rs

1use std::fmt::Display;
2
3use either::Either;
4
5use crate::analyzer::{JsValue, ModuleValue, ObjectPart};
6
7impl Display for ObjectPart<'_> {
8    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9        match self {
10            ObjectPart::KeyValue(key, value) => write!(f, "{key}: {value}"),
11            ObjectPart::Spread(value) => write!(f, "...{value}"),
12        }
13    }
14}
15
16impl Display for JsValue<'_> {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        match self {
19            JsValue::Constant(v) => write!(f, "{v}"),
20            JsValue::Url(url, kind) => write!(f, "{url} {kind}"),
21            JsValue::Array { items, mutable, .. } => write!(
22                f,
23                "{}[{}]",
24                if *mutable { "" } else { "frozen " },
25                items
26                    .iter()
27                    .map(|v| v.to_string())
28                    .collect::<Vec<_>>()
29                    .join(", ")
30            ),
31            JsValue::Object {
32                parts, mutability, ..
33            } => write!(
34                f,
35                "{}{{{}}}",
36                mutability,
37                parts
38                    .iter()
39                    .map(|v| v.to_string())
40                    .collect::<Vec<_>>()
41                    .join(", ")
42            ),
43            JsValue::Alternatives {
44                total_nodes: _,
45                values: list,
46                logical_property,
47            } => {
48                let list = list
49                    .iter()
50                    .map(|v| v.to_string())
51                    .collect::<Vec<_>>()
52                    .join(" | ");
53                if let Some(logical_property) = logical_property {
54                    write!(f, "({list}){{{logical_property}}}")
55                } else {
56                    write!(f, "({list})")
57                }
58            }
59            JsValue::FreeVar(name) => write!(f, "FreeVar({name:?})"),
60            JsValue::Variable(name) => write!(f, "Variable({}#{:?})", name.0, name.1),
61            JsValue::Concat(_, list) => write!(
62                f,
63                "`{}`",
64                list.iter()
65                    .map(|v| v
66                        .as_str()
67                        .map_or_else(|| format!("${{{v}}}"), |str| str.to_string()))
68                    .collect::<Vec<_>>()
69                    .join("")
70            ),
71            JsValue::Add(_, list) => write!(
72                f,
73                "({})",
74                list.iter()
75                    .map(|v| v.to_string())
76                    .collect::<Vec<_>>()
77                    .join(" + ")
78            ),
79            JsValue::Not(_, value) => write!(f, "!({value})"),
80            JsValue::Logical(_, op, list) => write!(
81                f,
82                "({})",
83                list.iter()
84                    .map(|v| v.to_string())
85                    .collect::<Vec<_>>()
86                    .join(op.joiner())
87            ),
88            JsValue::Binary(_, a, op, b) => write!(f, "({}{}{})", a, op.joiner(), b),
89            JsValue::Tenary(_, test, cons, alt) => write!(f, "({test} ? {cons} : {alt})"),
90            JsValue::New(_, call) => write!(
91                f,
92                "new {}({})",
93                call.callee(),
94                call.args()
95                    .iter()
96                    .map(|v| v.to_string())
97                    .collect::<Vec<_>>()
98                    .join(", ")
99            ),
100            JsValue::Call(_, call) => write!(
101                f,
102                "{}({})",
103                call.callee(),
104                call.args()
105                    .iter()
106                    .map(|v| v.to_string())
107                    .collect::<Vec<_>>()
108                    .join(", ")
109            ),
110            JsValue::SuperCall(_, args) => write!(
111                f,
112                "super({})",
113                args.iter()
114                    .map(|v| v.to_string())
115                    .collect::<Vec<_>>()
116                    .join(", ")
117            ),
118            JsValue::MemberCall(_, call) => write!(
119                f,
120                "{}[{}]({})",
121                call.obj(),
122                call.prop(),
123                call.args()
124                    .iter()
125                    .map(|v| v.to_string())
126                    .collect::<Vec<_>>()
127                    .join(", ")
128            ),
129            JsValue::Member(_, obj, prop) => write!(f, "{obj}[{prop}]"),
130            JsValue::In(_, left, right) => write!(f, "{left} in {right}"),
131            JsValue::Module(ModuleValue {
132                module: name,
133                annotations,
134                analyze_for_constants,
135                reference: _,
136            }) => {
137                write!(
138                    f,
139                    "Module({}, {}{})",
140                    name.to_string_lossy(),
141                    if let Some(annotations) = annotations {
142                        Either::Left(annotations)
143                    } else {
144                        Either::Right("{}")
145                    },
146                    if *analyze_for_constants {
147                        ", analyze for constants"
148                    } else {
149                        ""
150                    }
151                )
152            }
153            JsValue::Unknown { .. } => write!(f, "???"),
154            JsValue::WellKnownObject(obj) => write!(f, "WellKnownObject({obj:?})"),
155            JsValue::WellKnownFunction(func) => write!(f, "WellKnownFunction({func:?})"),
156            JsValue::Function(_, func_ident, return_value) => {
157                write!(f, "Function#{func_ident}(return = {return_value:?})")
158            }
159            JsValue::Argument(func_ident, index) => {
160                write!(f, "arguments[{index}#{func_ident}]")
161            }
162            JsValue::Iterated(_, iterable) => write!(f, "Iterated({iterable})"),
163            JsValue::TypeOf(_, operand) => write!(f, "typeof({operand})"),
164            JsValue::Promise(_, operand) => write!(f, "Promise<{operand}>"),
165            JsValue::Awaited(_, operand) => write!(f, "await({operand})"),
166        }
167    }
168}