Skip to content

Commit

Permalink
refactor: improve dependency location (web-infra-dev#8606)
Browse files Browse the repository at this point in the history
* refactor: improve dependency location

* chore: follow the suggestion
  • Loading branch information
shulaoda authored Dec 4, 2024
1 parent 4edb7ca commit 1702843
Show file tree
Hide file tree
Showing 30 changed files with 321 additions and 194 deletions.
10 changes: 6 additions & 4 deletions crates/rspack_core/src/build_chunk_graph/code_splitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use crate::incremental::{IncrementalPasses, Mutation};
use crate::{
assign_depths, get_entry_runtime, merge_runtime, AsyncDependenciesBlockIdentifier, ChunkGroup,
ChunkGroupKind, ChunkGroupOptions, ChunkGroupUkey, ChunkLoading, ChunkUkey, Compilation,
ConnectionState, DependenciesBlock, DependencyId, DependencyLocation, DependencyName,
EntryDependency, EntryRuntime, GroupOptions, Logger, ModuleDependency, ModuleGraph,
ModuleIdentifier, RuntimeSpec,
ConnectionState, DependenciesBlock, DependencyId, DependencyLocation, EntryDependency,
EntryRuntime, GroupOptions, Logger, ModuleDependency, ModuleGraph, ModuleIdentifier, RuntimeSpec,
SyntheticDependencyLocation,
};

type IndexMap<K, V, H = FxHasher> = RawIndexMap<K, V, BuildHasherDefault<H>>;
Expand Down Expand Up @@ -407,7 +407,9 @@ impl CodeSplitter {
));

for request in requests {
let loc = Some(DependencyLocation::Synthetic(DependencyName::new(name)));
let loc = Some(DependencyLocation::Synthetic(
SyntheticDependencyLocation::new(name),
));
entrypoint.add_origin(None, loc, request);
}

Expand Down
5 changes: 4 additions & 1 deletion crates/rspack_core/src/compiler/make/repair/factorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ impl Task<MakeTaskContext> for FactorizeTask {
return Err(e);
}
let mut diagnostics = Vec::with_capacity(create_data.diagnostics.len() + 1);
diagnostics.push(Into::<Diagnostic>::into(e).with_loc(create_data.dependencies[0].loc()));
diagnostics.push(
Into::<Diagnostic>::into(e)
.with_loc(create_data.dependencies[0].loc().map(|loc| loc.to_string())),
);
diagnostics.append(&mut create_data.diagnostics);
// Continue bundling if `options.bail` set to `false`.
Ok(vec![Box::new(
Expand Down
20 changes: 12 additions & 8 deletions crates/rspack_core/src/context_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use crate::{
BuildMetaDefaultObject, BuildMetaExportsType, BuildResult, ChunkGraph, ChunkGroupOptions,
CodeGenerationResult, Compilation, ConcatenationScope, ContextElementDependency,
DependenciesBlock, Dependency, DependencyCategory, DependencyId, DependencyLocation,
DependencyRange, DynamicImportMode, ExportsType, FactoryMeta, FakeNamespaceObjectMode,
GroupOptions, ImportAttributes, LibIdentOptions, Module, ModuleId, ModuleLayer, ModuleType,
Resolve, RuntimeGlobals, RuntimeSpec, SourceType,
DynamicImportMode, ExportsType, FactoryMeta, FakeNamespaceObjectMode, GroupOptions,
ImportAttributes, LibIdentOptions, Module, ModuleId, ModuleLayer, ModuleType,
RealDependencyLocation, Resolve, RuntimeGlobals, RuntimeSpec, SourceType,
};

static WEBPACK_CHUNK_NAME_INDEX_PLACEHOLDER: &str = "[index]";
Expand Down Expand Up @@ -879,13 +879,17 @@ impl Module for ContextModule {
if matches!(self.options.context_options.mode, ContextMode::LazyOnce)
&& !context_element_dependencies.is_empty()
{
let loc = DependencyRange::new(
self.options.context_options.start,
self.options.context_options.end,
);
let loc = DependencyLocation::Real(RealDependencyLocation::new(
(
self.options.context_options.start,
self.options.context_options.end,
)
.into(),
None,
));
let mut block = AsyncDependenciesBlock::new(
(*self.identifier).into(),
Some(DependencyLocation::Real(loc)),
Some(loc),
None,
context_element_dependencies
.into_iter()
Expand Down
134 changes: 91 additions & 43 deletions crates/rspack_core/src/dependency/dependency_location.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,24 @@
use std::{fmt, sync::Arc};
use std::{
fmt::{self, Debug},
sync::Arc,
};

use derivative::Derivative;

/// Represents a range in a dependency, typically used for tracking the span of code in a source file.
/// It stores the start and end positions (as offsets) of the range, typically using base-0 indexing.
#[derive(Derivative)]
#[derivative(Debug, Clone, Hash)]
pub struct DependencyRange {
pub end: u32,
pub start: u32,
#[derivative(Debug = "ignore", Hash = "ignore")]
source: Option<Arc<dyn SourceLocation>>,
}

impl DependencyRange {
pub fn new(start: u32, end: u32) -> Self {
DependencyRange {
end,
start,
source: None,
}
}

pub fn with_source(mut self, source: Arc<dyn SourceLocation>) -> Self {
self.source = Some(source);
self
}
}

impl From<(u32, u32)> for DependencyRange {
fn from(range: (u32, u32)) -> Self {
Self {
start: range.0,
end: range.1,
source: None,
}
}
}
Expand All @@ -41,58 +28,99 @@ impl From<swc_core::common::Span> for DependencyRange {
Self {
start: span.lo.0.saturating_sub(1),
end: span.hi.0.saturating_sub(1),
source: None,
}
}
}

impl fmt::Display for DependencyRange {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(source) = &self.source {
let (start, end) = source.look_up_range_pos(self.start, self.end);
impl DependencyRange {
pub fn new(start: u32, end: u32) -> Self {
DependencyRange { end, start }
}

if start.line == end.line {
if start.column == end.column {
return write!(f, "{}:{}", start.line, start.column);
/// Converts the `DependencyRange` into a `DependencyLocation`.
/// The `source` parameter is an optional source map used to resolve the exact position in the source file.
pub fn to_loc(&self, source: Option<&Arc<dyn SourceLocation>>) -> DependencyLocation {
DependencyLocation::Real(match source {
Some(source) => {
let (start, end) = source.look_up_range_pos(self.start, self.end);

if start.line == end.line && start.column == end.column {
RealDependencyLocation::new(start, None)
} else {
RealDependencyLocation::new(start, Some(end))
}

return write!(f, "{}:{}-{}", start.line, start.column, end.column);
}
None => RealDependencyLocation::new(
SourcePosition {
line: self.start as usize,
column: self.end as usize,
},
None,
),
})
}
}

write!(
f,
"{}:{}-{}:{}",
start.line, start.column, end.line, end.column
)
/// Represents the real location of a dependency in a source file, including both start and optional end positions.
/// These positions are described in terms of lines and columns in the source code.
#[derive(Debug, Clone)]
pub struct RealDependencyLocation {
start: SourcePosition,
end: Option<SourcePosition>,
}

impl RealDependencyLocation {
pub fn new(start: SourcePosition, end: Option<SourcePosition>) -> Self {
Self { start, end }
}
}

impl fmt::Display for RealDependencyLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(end) = self.end {
if self.start.line == end.line {
write!(
f,
"{}:{}-{}",
self.start.line, self.start.column, end.column
)
} else {
write!(
f,
"{}:{}-{}:{}",
self.start.line, self.start.column, end.line, end.column
)
}
} else {
write!(f, "{}:{}", self.start, self.end)
write!(f, "{}:{}", self.start.line, self.start.column)
}
}
}

/// Represents a synthetic dependency location, such as a generated dependency.
#[derive(Debug, Clone)]
pub struct DependencyName {
pub struct SyntheticDependencyLocation {
pub name: String,
}

impl DependencyName {
impl SyntheticDependencyLocation {
pub fn new(name: &str) -> Self {
DependencyName {
SyntheticDependencyLocation {
name: name.to_string(),
}
}
}

impl fmt::Display for DependencyName {
impl fmt::Display for SyntheticDependencyLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}

#[derive(Debug, Clone)]
pub enum DependencyLocation {
Real(DependencyRange),
Synthetic(DependencyName),
Real(RealDependencyLocation),
Synthetic(SyntheticDependencyLocation),
}

impl fmt::Display for DependencyLocation {
Expand All @@ -105,16 +133,33 @@ impl fmt::Display for DependencyLocation {
}
}

/// Represents a position in the source file, including the line number and column number.
#[derive(Debug, Clone, Copy)]
pub struct SourcePosition {
pub line: usize,
pub column: usize,
line: usize,
column: usize,
}

impl From<(u32, u32)> for SourcePosition {
fn from(range: (u32, u32)) -> Self {
Self {
line: range.0 as usize,
column: range.1 as usize,
}
}
}

/// Trait representing a source map that can resolve the positions of code ranges to source file positions.
pub trait SourceLocation: Send + Sync {
fn look_up_range_pos(&self, start: u32, end: u32) -> (SourcePosition, SourcePosition);
}

impl Debug for dyn SourceLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SourceMap").finish()
}
}

impl SourceLocation for swc_core::common::SourceMap {
fn look_up_range_pos(&self, start: u32, end: u32) -> (SourcePosition, SourcePosition) {
let lo = self.lookup_char_pos(swc_core::common::BytePos(start + 1));
Expand All @@ -132,3 +177,6 @@ impl SourceLocation for swc_core::common::SourceMap {
)
}
}

/// Type alias for a shared reference to a `SourceLocation` trait object, typically used for source maps.
pub type SharedSourceMap = Arc<dyn SourceLocation>;
3 changes: 2 additions & 1 deletion crates/rspack_core/src/dependency/dependency_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use swc_core::ecma::atoms::Atom;

use super::dependency_template::AsDependencyTemplate;
use super::module_dependency::*;
use super::DependencyLocation;
use super::DependencyRange;
use super::ExportsSpec;
use super::{DependencyCategory, DependencyId, DependencyType};
Expand Down Expand Up @@ -74,7 +75,7 @@ pub trait Dependency:
ConnectionState::Bool(true)
}

fn loc(&self) -> Option<String> {
fn loc(&self) -> Option<DependencyLocation> {
None
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rspack_core::{
module_id, property_access, to_normal_comment, Compilation, DependencyRange, ExportsType,
ExtendedReferencedExport, ModuleGraph, RuntimeGlobals, RuntimeSpec, UsedName,
module_id, property_access, to_normal_comment, Compilation, DependencyLocation, DependencyRange,
ExportsType, ExtendedReferencedExport, ModuleGraph, RuntimeGlobals, RuntimeSpec, SharedSourceMap,
UsedName,
};
use rspack_core::{AsContextDependency, Dependency, DependencyCategory};
use rspack_core::{DependencyId, DependencyTemplate};
Expand All @@ -17,6 +18,7 @@ pub struct CommonJsFullRequireDependency {
is_call: bool,
optional: bool,
asi_safe: bool,
source_map: Option<SharedSourceMap>,
}

impl CommonJsFullRequireDependency {
Expand All @@ -27,6 +29,7 @@ impl CommonJsFullRequireDependency {
is_call: bool,
optional: bool,
asi_safe: bool,
source_map: Option<SharedSourceMap>,
) -> Self {
Self {
id: DependencyId::new(),
Expand All @@ -36,6 +39,7 @@ impl CommonJsFullRequireDependency {
is_call,
optional,
asi_safe,
source_map,
}
}
}
Expand All @@ -53,8 +57,8 @@ impl Dependency for CommonJsFullRequireDependency {
&DependencyType::CjsRequire
}

fn loc(&self) -> Option<String> {
Some(self.range.to_string())
fn loc(&self) -> Option<DependencyLocation> {
Some(self.range.to_loc(self.source_map.as_ref()))
}

fn range(&self) -> Option<&DependencyRange> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use rspack_core::{module_id, Compilation, DependencyRange, RuntimeSpec};
use rspack_core::{
module_id, Compilation, DependencyLocation, DependencyRange, RuntimeSpec, SharedSourceMap,
};
use rspack_core::{AsContextDependency, Dependency, DependencyCategory};
use rspack_core::{DependencyId, DependencyTemplate};
use rspack_core::{DependencyType, ModuleDependency};
Expand All @@ -11,6 +13,7 @@ pub struct CommonJsRequireDependency {
optional: bool,
range: DependencyRange,
range_expr: Option<DependencyRange>,
source_map: Option<SharedSourceMap>,
}

impl CommonJsRequireDependency {
Expand All @@ -19,13 +22,15 @@ impl CommonJsRequireDependency {
range: DependencyRange,
range_expr: Option<DependencyRange>,
optional: bool,
source_map: Option<SharedSourceMap>,
) -> Self {
Self {
id: DependencyId::new(),
request,
optional,
range,
range_expr,
source_map,
}
}
}
Expand All @@ -35,8 +40,8 @@ impl Dependency for CommonJsRequireDependency {
&self.id
}

fn loc(&self) -> Option<String> {
Some(self.range.to_string())
fn loc(&self) -> Option<DependencyLocation> {
Some(self.range.to_loc(self.source_map.as_ref()))
}

fn category(&self) -> &DependencyCategory {
Expand Down
Loading

0 comments on commit 1702843

Please sign in to comment.