turbopack_ecmascript/analyzer/jsvalue/
display.rs1use 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}