Skip to main content

rspack_core/dependency/
runtime_requirements_dependency.rs

1use rspack_cacheable::{cacheable, cacheable_dyn};
2use rspack_util::ext::DynHash;
3
4use crate::{
5  Compilation, DependencyCodeGeneration, DependencyRange, DependencyTemplate,
6  DependencyTemplateType, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource,
7};
8
9#[cacheable]
10#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
11pub enum RuntimeRequirementsDependencyMode {
12  #[default]
13  Normal,
14  Call,
15  AddOnly,
16}
17
18#[cacheable]
19#[derive(Debug, Clone)]
20pub struct RuntimeRequirementsDependency {
21  pub range: DependencyRange,
22  pub runtime_requirements: RuntimeGlobals,
23  pub mode: RuntimeRequirementsDependencyMode,
24}
25
26#[cacheable_dyn]
27impl DependencyCodeGeneration for RuntimeRequirementsDependency {
28  fn dependency_template(&self) -> Option<DependencyTemplateType> {
29    Some(RuntimeRequirementsDependencyTemplate::template_type())
30  }
31
32  fn update_hash(
33    &self,
34    hasher: &mut dyn std::hash::Hasher,
35    _compilation: &Compilation,
36    _runtime: Option<&RuntimeSpec>,
37  ) {
38    self.range.dyn_hash(hasher);
39    self.runtime_requirements.dyn_hash(hasher);
40    self.mode.dyn_hash(hasher);
41  }
42}
43
44impl RuntimeRequirementsDependency {
45  pub fn new(range: DependencyRange, runtime_requirements: RuntimeGlobals) -> Self {
46    Self {
47      range,
48      runtime_requirements,
49      mode: RuntimeRequirementsDependencyMode::Normal,
50    }
51  }
52  pub fn call(range: DependencyRange, runtime_requirements: RuntimeGlobals) -> Self {
53    Self {
54      range,
55      runtime_requirements,
56      mode: RuntimeRequirementsDependencyMode::Call,
57    }
58  }
59  pub fn add_only(runtime_requirements: RuntimeGlobals) -> Self {
60    Self {
61      range: DependencyRange::default(),
62      runtime_requirements,
63      mode: RuntimeRequirementsDependencyMode::AddOnly,
64    }
65  }
66}
67
68#[cacheable]
69#[derive(Debug, Clone, Default)]
70pub struct RuntimeRequirementsDependencyTemplate;
71
72impl RuntimeRequirementsDependencyTemplate {
73  pub fn template_type() -> DependencyTemplateType {
74    DependencyTemplateType::Custom("RuntimeRequirementsDependency")
75  }
76}
77
78impl DependencyTemplate for RuntimeRequirementsDependencyTemplate {
79  fn render(
80    &self,
81    dep: &dyn DependencyCodeGeneration,
82    source: &mut TemplateReplaceSource,
83    code_generatable_context: &mut TemplateContext,
84  ) {
85    let dep = dep
86      .as_any()
87      .downcast_ref::<RuntimeRequirementsDependency>()
88      .expect(
89        "RuntimeRequirementsDependencyTemplate should be used for RuntimeRequirementsDependency",
90      );
91
92    if matches!(dep.mode, RuntimeRequirementsDependencyMode::AddOnly) {
93      code_generatable_context
94        .runtime_template
95        .runtime_requirements_mut()
96        .insert(dep.runtime_requirements);
97      return;
98    }
99
100    let mut content = code_generatable_context
101      .runtime_template
102      .render_runtime_globals(&dep.runtime_requirements);
103
104    if matches!(dep.mode, RuntimeRequirementsDependencyMode::Call) {
105      content = format!("{content}()");
106    }
107
108    source.replace(dep.range.start, dep.range.end, content, None);
109  }
110}