1use swc_core::ecma::atoms::Atom;
2
3use crate::analyzer::{ConstantString, JsValue, RequireContextValue};
4
5#[derive(Debug, Clone, Hash, PartialEq, Eq)]
7pub enum WellKnownObjectKind {
8 GlobalObject,
9 PathModule,
10 PathModuleDefault,
11 FsModule,
12 FsModuleDefault,
13 FsModulePromises,
14 FsExtraModule,
15 FsExtraModuleDefault,
16 GracefulFsModule,
17 GracefulFsModuleDefault,
18 ModuleModule,
19 ModuleModuleDefault,
20 UrlModule,
21 UrlModuleDefault,
22 WorkerThreadsModule,
23 WorkerThreadsModuleDefault,
24 ChildProcessModule,
25 ChildProcessModuleDefault,
26 OsModule,
27 OsModuleDefault,
28 NodeProcessModule,
29 NodeProcessArgv,
30 NodeProcessEnv,
31 NodePreGyp,
32 NodeExpressApp,
33 NodeProtobufLoader,
34 NodeBuffer,
35 RequireCache,
36 ImportMeta,
37 ImportMetaEnv,
38 Generator,
40 ModuleHot,
42 Navigator,
44 NavigatorServiceWorker,
46}
47
48impl WellKnownObjectKind {
49 pub fn as_define_name(&self) -> Option<&[&str]> {
50 match self {
51 Self::GlobalObject => Some(&["Object"]),
52 Self::PathModule => Some(&["path"]),
53 Self::FsModule => Some(&["fs"]),
54 Self::UrlModule => Some(&["url"]),
55 Self::ChildProcessModule => Some(&["child_process"]),
56 Self::OsModule => Some(&["os"]),
57 Self::WorkerThreadsModule => Some(&["worker_threads"]),
58 Self::NodeProcessModule => Some(&["process"]),
59 Self::NodeProcessArgv => Some(&["process", "argv"]),
60 Self::NodeProcessEnv => Some(&["process", "env"]),
61 Self::NodeBuffer => Some(&["Buffer"]),
62 Self::RequireCache => Some(&["require", "cache"]),
63 Self::ImportMeta => Some(&["import", "meta"]),
64 _ => None,
65 }
66 }
67
68 pub fn explain(&self) -> (&'static str, &'static str) {
71 match self {
72 Self::Generator => (
73 "Generator",
74 "A Generator or AsyncGenerator object: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator",
75 ),
76 Self::GlobalObject => ("Object", "The global Object variable"),
77 Self::PathModule | Self::PathModuleDefault => (
78 "path",
79 "The Node.js path module: https://nodejs.org/api/path.html",
80 ),
81 Self::FsModule | Self::FsModuleDefault => (
82 "fs",
83 "The Node.js fs module: https://nodejs.org/api/fs.html",
84 ),
85 Self::FsExtraModule | Self::FsExtraModuleDefault => (
86 "fs-extra",
87 "The Node.js fs-extra module: https://github.com/jprichardson/node-fs-extra",
88 ),
89 Self::GracefulFsModule | Self::GracefulFsModuleDefault => (
90 "graceful-fs",
91 "The Node.js graceful-fs module: https://github.com/isaacs/node-graceful-fs",
92 ),
93 Self::FsModulePromises => (
94 "fs/promises",
95 "The Node.js fs module: https://nodejs.org/api/fs.html#promises-api",
96 ),
97 Self::UrlModule | Self::UrlModuleDefault => (
98 "url",
99 "The Node.js url module: https://nodejs.org/api/url.html",
100 ),
101 Self::ModuleModule | Self::ModuleModuleDefault => (
102 "module",
103 "The Node.js `module` module: https://nodejs.org/api/module.html",
104 ),
105 Self::WorkerThreadsModule | Self::WorkerThreadsModuleDefault => (
106 "worker_threads",
107 "The Node.js `worker_threads` module: https://nodejs.org/api/worker_threads.html",
108 ),
109 Self::ChildProcessModule | Self::ChildProcessModuleDefault => (
110 "child_process",
111 "The Node.js child_process module: https://nodejs.org/api/child_process.html",
112 ),
113 Self::OsModule | Self::OsModuleDefault => (
114 "os",
115 "The Node.js os module: https://nodejs.org/api/os.html",
116 ),
117 Self::NodeProcessModule => (
118 "process",
119 "The Node.js process module: https://nodejs.org/api/process.html",
120 ),
121 Self::NodeProcessArgv => (
122 "process.argv",
123 "The Node.js process.argv property: https://nodejs.org/api/process.html#processargv",
124 ),
125 Self::NodeProcessEnv => (
126 "process.env",
127 "The Node.js process.env property: https://nodejs.org/api/process.html#processenv",
128 ),
129 Self::NodePreGyp => (
130 "@mapbox/node-pre-gyp",
131 "The Node.js @mapbox/node-pre-gyp module: https://github.com/mapbox/node-pre-gyp",
132 ),
133 Self::NodeExpressApp => (
134 "express",
135 "The Node.js express package: https://github.com/expressjs/express",
136 ),
137 Self::NodeProtobufLoader => (
138 "@grpc/proto-loader",
139 "The Node.js @grpc/proto-loader package: https://github.com/grpc/grpc-node",
140 ),
141 Self::NodeBuffer => (
142 "Buffer",
143 "The Node.js Buffer object: https://nodejs.org/api/buffer.html#class-buffer",
144 ),
145 Self::RequireCache => (
146 "require.cache",
147 "The CommonJS require.cache object: https://nodejs.org/api/modules.html#requirecache",
148 ),
149 Self::ImportMeta => ("import.meta", "The import.meta object"),
150 Self::ImportMetaEnv => ("import.meta.env", "The import.meta.env object"),
151 Self::ModuleHot => ("module.hot", "The module.hot HMR API"),
152 Self::Navigator => (
153 "navigator",
154 "The browser navigator global: https://developer.mozilla.org/en-US/docs/Web/API/Navigator",
155 ),
156 Self::NavigatorServiceWorker => (
157 "navigator.serviceWorker",
158 "The ServiceWorkerContainer: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer",
159 ),
160 }
161 }
162}
163
164#[derive(Debug, Clone, Hash, PartialEq)]
166pub enum WellKnownFunctionKind<'a> {
167 ArrayFilter,
168 ArrayForEach,
169 ArrayMap,
170 ObjectAssign,
171 PathJoin,
172 PathDirname,
173 PathResolve(&'a JsValue<'a>),
175 Import,
176 Require,
177 RequireFrom(Box<ConstantString>),
179 RequireResolve,
180 RequireContext,
181 RequireContextRequire(Box<RequireContextValue>),
184 RequireContextRequireKeys(Box<RequireContextValue>),
185 RequireContextRequireResolve(Box<RequireContextValue>),
186 Define,
187 FsReadMethod(Atom),
188 FsReadDir,
189 PathToFileUrl,
190 CreateRequire,
191 ChildProcessSpawnMethod(Atom),
192 ChildProcessFork,
193 OsArch,
194 OsPlatform,
195 OsEndianness,
196 ProcessCwd,
197 NodePreGypFind,
198 NodeGypBuild,
199 NodeBindings,
200 NodeExpress,
201 NodeExpressSet,
202 NodeStrongGlobalize,
203 NodeStrongGlobalizeSetRootDir,
204 NodeResolveFrom,
205 NodeProtobufLoad,
206 WorkerConstructor,
207 SharedWorkerConstructor,
208 NodeWorkerConstructor,
210 ServiceWorkerRegister,
212 URLConstructor,
213 ModuleHotAccept,
215 ModuleHotDecline,
217 ImportMetaGlob,
219 TurbopackEmit,
221 TurbopackCollect,
223}
224
225impl WellKnownFunctionKind<'_> {
226 pub fn as_define_name(&self) -> Option<&[&str]> {
227 match self {
228 Self::Import { .. } => Some(&["import"]),
229 Self::Require { .. } => Some(&["require"]),
230 Self::RequireResolve => Some(&["require", "resolve"]),
231 Self::RequireContext => Some(&["require", "context"]),
232 Self::Define => Some(&["define"]),
233 _ => None,
234 }
235 }
236
237 pub fn explain(&self) -> (String, &'static str) {
240 match self {
241 Self::ArrayFilter => (
242 "Array.prototype.filter".to_string(),
243 "The standard Array.prototype.filter method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter",
244 ),
245 Self::ArrayForEach => (
246 "Array.prototype.forEach".to_string(),
247 "The standard Array.prototype.forEach method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach",
248 ),
249 Self::ArrayMap => (
250 "Array.prototype.map".to_string(),
251 "The standard Array.prototype.map method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map",
252 ),
253 Self::ObjectAssign => (
254 "Object.assign".to_string(),
255 "Object.assign method: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign",
256 ),
257 Self::PathJoin => (
258 "path.join".to_string(),
259 "The Node.js path.join method: https://nodejs.org/api/path.html#pathjoinpaths",
260 ),
261 Self::PathDirname => (
262 "path.dirname".to_string(),
263 "The Node.js path.dirname method: https://nodejs.org/api/path.html#pathdirnamepath",
264 ),
265 Self::PathResolve(cwd) => (
266 format!("path.resolve({cwd})"),
267 "The Node.js path.resolve method: https://nodejs.org/api/path.html#pathresolvepaths",
268 ),
269 Self::Import => (
270 "import".to_string(),
271 "The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports",
272 ),
273 Self::Require => ("require".to_string(), "The require method from CommonJS"),
274 Self::RequireFrom(rel) => (
275 format!("createRequire('{rel}')"),
276 "The return value of Node.js module.createRequire: https://nodejs.org/api/module.html#modulecreaterequirefilename",
277 ),
278 Self::RequireResolve => (
279 "require.resolve".to_string(),
280 "The require.resolve method from CommonJS",
281 ),
282 Self::RequireContext => (
283 "require.context".to_string(),
284 "The require.context method from webpack",
285 ),
286 Self::RequireContextRequire(..) => (
287 "require.context(...)".to_string(),
288 "The require.context(...) method from webpack: https://webpack.js.org/api/module-methods/#requirecontext",
289 ),
290 Self::RequireContextRequireKeys(..) => (
291 "require.context(...).keys".to_string(),
292 "The require.context(...).keys method from webpack: https://webpack.js.org/guides/dependency-management/#requirecontext",
293 ),
294 Self::RequireContextRequireResolve(..) => (
295 "require.context(...).resolve".to_string(),
296 "The require.context(...).resolve method from webpack: https://webpack.js.org/guides/dependency-management/#requirecontext",
297 ),
298 Self::Define => ("define".to_string(), "The define method from AMD"),
299 Self::FsReadMethod(name) => (
300 format!("fs.{name}"),
301 "A file reading method from the Node.js fs module: https://nodejs.org/api/fs.html",
302 ),
303 Self::FsReadDir => (
304 "fs.readdir".to_string(),
305 "The Node.js fs.readdir method: https://nodejs.org/api/fs.html",
306 ),
307 Self::PathToFileUrl => (
308 "url.pathToFileURL".to_string(),
309 "The Node.js url.pathToFileURL method: https://nodejs.org/api/url.html#urlpathtofileurlpath",
310 ),
311 Self::CreateRequire => (
312 "module.createRequire".to_string(),
313 "The Node.js module.createRequire method: https://nodejs.org/api/module.html#modulecreaterequirefilename",
314 ),
315 Self::ChildProcessSpawnMethod(name) => (
316 format!("child_process.{name}"),
317 "A process spawning method from the Node.js child_process module: https://nodejs.org/api/child_process.html",
318 ),
319 Self::ChildProcessFork => (
320 "child_process.fork".to_string(),
321 "The Node.js child_process.fork method: https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options",
322 ),
323 Self::OsArch => (
324 "os.arch".to_string(),
325 "The Node.js os.arch method: https://nodejs.org/api/os.html#os_os_arch",
326 ),
327 Self::OsPlatform => (
328 "os.process".to_string(),
329 "The Node.js os.process method: https://nodejs.org/api/os.html#os_os_process",
330 ),
331 Self::OsEndianness => (
332 "os.endianness".to_string(),
333 "The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness",
334 ),
335 Self::ProcessCwd => (
336 "process.cwd".to_string(),
337 "The Node.js process.cwd method: https://nodejs.org/api/process.html#processcwd",
338 ),
339 Self::NodePreGypFind => (
340 "binary.find".to_string(),
341 "The Node.js @mapbox/node-pre-gyp module: https://github.com/mapbox/node-pre-gyp",
342 ),
343 Self::NodeGypBuild => (
344 "node-gyp-build".to_string(),
345 "The Node.js node-gyp-build module: https://github.com/prebuild/node-gyp-build",
346 ),
347 Self::NodeBindings => (
348 "bindings".to_string(),
349 "The Node.js bindings module: https://github.com/TooTallNate/node-bindings",
350 ),
351 Self::NodeExpress => (
352 "express".to_string(),
353 "require('express')() : https://github.com/expressjs/express",
354 ),
355 Self::NodeExpressSet => (
356 "set".to_string(),
357 "require('express')().set('view engine', 'jade') https://github.com/expressjs/express",
358 ),
359 Self::NodeStrongGlobalize => (
360 "SetRootDir".to_string(),
361 "require('strong-globalize')() https://github.com/strongloop/strong-globalize",
362 ),
363 Self::NodeStrongGlobalizeSetRootDir => (
364 "SetRootDir".to_string(),
365 "require('strong-globalize').SetRootDir(__dirname) https://github.com/strongloop/strong-globalize",
366 ),
367 Self::NodeResolveFrom => (
368 "resolveFrom".to_string(),
369 "require('resolve-from')(__dirname, 'node-gyp/bin/node-gyp') https://github.com/sindresorhus/resolve-from",
370 ),
371 Self::NodeProtobufLoad => (
372 "load/loadSync".to_string(),
373 "require('@grpc/proto-loader').load(filepath, { includeDirs: [root] }) https://github.com/grpc/grpc-node",
374 ),
375 Self::NodeWorkerConstructor => (
376 "Worker".to_string(),
377 "The Node.js worker_threads Worker constructor: https://nodejs.org/api/worker_threads.html#worker_threads_class_worker",
378 ),
379 Self::WorkerConstructor => (
380 "Worker".to_string(),
381 "The standard Worker constructor: https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker",
382 ),
383 Self::SharedWorkerConstructor => (
384 "SharedWorker".to_string(),
385 "The standard SharedWorker constructor: https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker",
386 ),
387 Self::ServiceWorkerRegister => (
388 "navigator.serviceWorker.register".to_string(),
389 "The ServiceWorkerContainer.register method: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register",
390 ),
391 Self::URLConstructor => (
392 "URL".to_string(),
393 "The standard URL constructor: https://developer.mozilla.org/en-US/docs/Web/API/URL/URL",
394 ),
395 Self::ModuleHotAccept => (
396 "module.hot.accept".to_string(),
397 "The module.hot.accept HMR API: https://webpack.js.org/api/hot-module-replacement/#accept",
398 ),
399 Self::ModuleHotDecline => (
400 "module.hot.decline".to_string(),
401 "The module.hot.decline HMR API: https://webpack.js.org/api/hot-module-replacement/#decline",
402 ),
403 Self::ImportMetaGlob => (
404 "import.meta.glob".to_string(),
405 "The import.meta.glob() function from Vite: https://vite.dev/guide/features.html#glob-import",
406 ),
407 Self::TurbopackEmit => (
408 "__turbopack_emit__".to_string(),
409 "The __turbopack_emit__ function for emitting data to the bundler"
410 ),
411 Self::TurbopackCollect => (
412 "__turbopack_collect__".to_string(),
413 "The __turbopack_collect__ function for collecting emitted data from the bundler"
414 )
415 }
416 }
417}