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 { parts, mutable, .. } => write!(
32                f,
33                "{}{{{}}}",
34                if *mutable { "" } else { "frozen " },
35                parts
36                    .iter()
37                    .map(|v| v.to_string())
38                    .collect::<Vec<_>>()
39                    .join(", ")
40            ),
41            JsValue::Alternatives {
42                total_nodes: _,
43                values: list,
44                logical_property,
45            } => {
46                let list = list
47                    .iter()
48                    .map(|v| v.to_string())
49                    .collect::<Vec<_>>()
50                    .join(" | ");
51                if let Some(logical_property) = logical_property {
52                    write!(f, "({list}){{{logical_property}}}")
53                } else {
54                    write!(f, "({list})")
55                }
56            }
57            JsValue::FreeVar(name) => write!(f, "FreeVar({name:?})"),
58            JsValue::Variable(name) => write!(f, "Variable({}#{:?})", name.0, name.1),
59            JsValue::Concat(_, list) => write!(
60                f,
61                "`{}`",
62                list.iter()
63                    .map(|v| v
64                        .as_str()
65                        .map_or_else(|| format!("${{{v}}}"), |str| str.to_string()))
66                    .collect::<Vec<_>>()
67                    .join("")
68            ),
69            JsValue::Add(_, list) => write!(
70                f,
71                "({})",
72                list.iter()
73                    .map(|v| v.to_string())
74                    .collect::<Vec<_>>()
75                    .join(" + ")
76            ),
77            JsValue::Not(_, value) => write!(f, "!({value})"),
78            JsValue::Logical(_, op, list) => write!(
79                f,
80                "({})",
81                list.iter()
82                    .map(|v| v.to_string())
83                    .collect::<Vec<_>>()
84                    .join(op.joiner())
85            ),
86            JsValue::Binary(_, a, op, b) => write!(f, "({}{}{})", a, op.joiner(), b),
87            JsValue::Tenary(_, test, cons, alt) => write!(f, "({test} ? {cons} : {alt})"),
88            JsValue::New(_, call) => write!(
89                f,
90                "new {}({})",
91                call.callee(),
92                call.args()
93                    .iter()
94                    .map(|v| v.to_string())
95                    .collect::<Vec<_>>()
96                    .join(", ")
97            ),
98            JsValue::Call(_, call) => write!(
99                f,
100                "{}({})",
101                call.callee(),
102                call.args()
103                    .iter()
104                    .map(|v| v.to_string())
105                    .collect::<Vec<_>>()
106                    .join(", ")
107            ),
108            JsValue::SuperCall(_, args) => write!(
109                f,
110                "super({})",
111                args.iter()
112                    .map(|v| v.to_string())
113                    .collect::<Vec<_>>()
114                    .join(", ")
115            ),
116            JsValue::MemberCall(_, call) => write!(
117                f,
118                "{}[{}]({})",
119                call.obj(),
120                call.prop(),
121                call.args()
122                    .iter()
123                    .map(|v| v.to_string())
124                    .collect::<Vec<_>>()
125                    .join(", ")
126            ),
127            JsValue::Member(_, obj, prop) => write!(f, "{obj}[{prop}]"),
128            JsValue::In(_, left, right) => write!(f, "{left} in {right}"),
129            JsValue::Module(ModuleValue {
130                module: name,
131                annotations,
132            }) => {
133                write!(
134                    f,
135                    "Module({}, {})",
136                    name.to_string_lossy(),
137                    if let Some(annotations) = annotations {
138                        Either::Left(annotations)
139                    } else {
140                        Either::Right("{}")
141                    }
142                )
143            }
144            JsValue::Unknown { .. } => write!(f, "???"),
145            JsValue::WellKnownObject(obj) => write!(f, "WellKnownObject({obj:?})"),
146            JsValue::WellKnownFunction(func) => write!(f, "WellKnownFunction({func:?})"),
147            JsValue::Function(_, func_ident, return_value) => {
148                write!(f, "Function#{func_ident}(return = {return_value:?})")
149            }
150            JsValue::Argument(func_ident, index) => {
151                write!(f, "arguments[{index}#{func_ident}]")
152            }
153            JsValue::Iterated(_, iterable) => write!(f, "Iterated({iterable})"),
154            JsValue::TypeOf(_, operand) => write!(f, "typeof({operand})"),
155            JsValue::Promise(_, operand) => write!(f, "Promise<{operand}>"),
156            JsValue::Awaited(_, operand) => write!(f, "await({operand})"),
157        }
158    }
159}