|
| 1 | +use bitflags::bitflags; |
1 | 2 | use rspack_util::atom::Atom; |
2 | 3 | use rustc_hash::FxHashSet; |
| 4 | +use smallvec::SmallVec; |
3 | 5 |
|
4 | 6 | use crate::{ExportInfo, ExportInfoData, ExportsInfoArtifact, RuntimeSpec, UsageState}; |
5 | 7 |
|
6 | | -/// refer https://github.com/webpack/webpack/blob/d15c73469fd71cf98734685225250148b68ddc79/lib/FlagDependencyUsagePlugin.js#L64 |
7 | | -#[derive(Clone, Debug)] |
8 | | -pub enum ExtendedReferencedExport { |
9 | | - Array(Vec<Atom>), |
10 | | - Export(ReferencedExport), |
| 8 | +pub type ReferencedExportPath = SmallVec<[Atom; 2]>; |
| 9 | + |
| 10 | +bitflags! { |
| 11 | + #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
| 12 | + pub struct ReferencedExportFlags: u8 { |
| 13 | + const CAN_MANGLE = 1 << 0; |
| 14 | + const CAN_INLINE = 1 << 1; |
| 15 | + const NS_ACCESS = 1 << 2; |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +impl Default for ReferencedExportFlags { |
| 20 | + fn default() -> Self { |
| 21 | + Self::CAN_MANGLE | Self::CAN_INLINE |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +impl ReferencedExportFlags { |
| 26 | + #[inline] |
| 27 | + pub fn merge(&mut self, other: Self) { |
| 28 | + self.set( |
| 29 | + Self::CAN_MANGLE, |
| 30 | + self.contains(Self::CAN_MANGLE) && other.contains(Self::CAN_MANGLE), |
| 31 | + ); |
| 32 | + self.set( |
| 33 | + Self::CAN_INLINE, |
| 34 | + self.contains(Self::CAN_INLINE) && other.contains(Self::CAN_INLINE), |
| 35 | + ); |
| 36 | + self.set( |
| 37 | + Self::NS_ACCESS, |
| 38 | + self.contains(Self::NS_ACCESS) || other.contains(Self::NS_ACCESS), |
| 39 | + ); |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +#[derive(Clone, Debug, Default)] |
| 44 | +pub struct ReferencedExport { |
| 45 | + pub name: ReferencedExportPath, |
| 46 | + pub flags: ReferencedExportFlags, |
11 | 47 | } |
12 | 48 |
|
13 | | -pub fn is_no_exports_referenced(exports: &[ExtendedReferencedExport]) -> bool { |
| 49 | +pub fn is_no_exports_referenced(exports: &[ReferencedExport]) -> bool { |
14 | 50 | exports.is_empty() |
15 | 51 | } |
16 | 52 |
|
17 | | -pub fn is_exports_object_referenced(exports: &[ExtendedReferencedExport]) -> bool { |
18 | | - matches!(exports[..], [ExtendedReferencedExport::Array(ref arr)] if arr.is_empty()) |
| 53 | +pub fn is_exports_object_referenced(exports: &[ReferencedExport]) -> bool { |
| 54 | + matches!(exports, [export] if export.name.is_empty()) |
19 | 55 | } |
20 | 56 |
|
21 | | -pub fn create_no_exports_referenced() -> Vec<ExtendedReferencedExport> { |
| 57 | +pub fn create_no_exports_referenced() -> Vec<ReferencedExport> { |
22 | 58 | vec![] |
23 | 59 | } |
24 | 60 |
|
25 | | -pub fn create_exports_object_referenced() -> Vec<ExtendedReferencedExport> { |
26 | | - vec![ExtendedReferencedExport::Array(vec![])] |
| 61 | +pub fn create_exports_object_referenced() -> Vec<ReferencedExport> { |
| 62 | + vec![ReferencedExport::default()] |
27 | 63 | } |
28 | 64 |
|
29 | | -impl From<Vec<Atom>> for ExtendedReferencedExport { |
| 65 | +impl From<Vec<Atom>> for ReferencedExport { |
| 66 | + #[inline] |
30 | 67 | fn from(value: Vec<Atom>) -> Self { |
31 | | - ExtendedReferencedExport::Array(value) |
| 68 | + Self::from(ReferencedExportPath::from_vec(value)) |
32 | 69 | } |
33 | 70 | } |
34 | | -impl From<ReferencedExport> for ExtendedReferencedExport { |
35 | | - fn from(value: ReferencedExport) -> Self { |
36 | | - ExtendedReferencedExport::Export(value) |
| 71 | + |
| 72 | +impl From<Vec<&Atom>> for ReferencedExport { |
| 73 | + #[inline] |
| 74 | + fn from(value: Vec<&Atom>) -> Self { |
| 75 | + Self::from(value.into_iter().cloned().collect::<ReferencedExportPath>()) |
37 | 76 | } |
38 | 77 | } |
39 | 78 |
|
40 | | -#[derive(Clone, Debug)] |
41 | | -pub struct ReferencedExport { |
42 | | - pub name: Vec<Atom>, |
43 | | - pub can_mangle: bool, |
44 | | - pub can_inline: bool, |
45 | | - pub ns_access: bool, |
| 79 | +impl From<&[Atom]> for ReferencedExport { |
| 80 | + #[inline] |
| 81 | + fn from(value: &[Atom]) -> Self { |
| 82 | + Self::from(ReferencedExportPath::from(value)) |
| 83 | + } |
46 | 84 | } |
47 | 85 |
|
48 | | -impl ReferencedExport { |
49 | | - pub fn new(name: Vec<Atom>, can_mangle: bool, can_inline: bool) -> Self { |
| 86 | +impl From<ReferencedExportPath> for ReferencedExport { |
| 87 | + #[inline] |
| 88 | + fn from(name: ReferencedExportPath) -> Self { |
50 | 89 | Self { |
51 | 90 | name, |
52 | | - can_mangle, |
53 | | - can_inline, |
54 | | - ns_access: false, |
| 91 | + flags: ReferencedExportFlags::default(), |
55 | 92 | } |
56 | 93 | } |
57 | 94 | } |
58 | 95 |
|
59 | | -impl Default for ReferencedExport { |
60 | | - fn default() -> Self { |
61 | | - Self { |
62 | | - name: vec![], |
63 | | - can_mangle: true, |
64 | | - can_inline: true, |
65 | | - ns_access: false, |
66 | | - } |
| 96 | +impl From<Atom> for ReferencedExport { |
| 97 | + #[inline] |
| 98 | + fn from(value: Atom) -> Self { |
| 99 | + let mut path = ReferencedExportPath::new(); |
| 100 | + path.push(value); |
| 101 | + Self::from(path) |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +impl From<&Atom> for ReferencedExport { |
| 106 | + #[inline] |
| 107 | + fn from(value: &Atom) -> Self { |
| 108 | + Self::from(value.clone()) |
| 109 | + } |
| 110 | +} |
| 111 | + |
| 112 | +impl ReferencedExport { |
| 113 | + #[inline] |
| 114 | + pub fn with_can_mangle(mut self, can_mangle: bool) -> Self { |
| 115 | + self |
| 116 | + .flags |
| 117 | + .set(ReferencedExportFlags::CAN_MANGLE, can_mangle); |
| 118 | + self |
| 119 | + } |
| 120 | + |
| 121 | + #[inline] |
| 122 | + pub fn with_can_inline(mut self, can_inline: bool) -> Self { |
| 123 | + self |
| 124 | + .flags |
| 125 | + .set(ReferencedExportFlags::CAN_INLINE, can_inline); |
| 126 | + self |
| 127 | + } |
| 128 | + |
| 129 | + #[inline] |
| 130 | + pub fn with_ns_access(mut self, ns_access: bool) -> Self { |
| 131 | + self.flags.set(ReferencedExportFlags::NS_ACCESS, ns_access); |
| 132 | + self |
| 133 | + } |
| 134 | + |
| 135 | + #[inline] |
| 136 | + pub fn can_mangle(&self) -> bool { |
| 137 | + self.flags.contains(ReferencedExportFlags::CAN_MANGLE) |
| 138 | + } |
| 139 | + |
| 140 | + #[inline] |
| 141 | + pub fn can_inline(&self) -> bool { |
| 142 | + self.flags.contains(ReferencedExportFlags::CAN_INLINE) |
| 143 | + } |
| 144 | + |
| 145 | + #[inline] |
| 146 | + pub fn ns_access(&self) -> bool { |
| 147 | + self.flags.contains(ReferencedExportFlags::NS_ACCESS) |
67 | 148 | } |
68 | 149 | } |
69 | 150 |
|
|
0 commit comments