diff --git a/crates/turbopack-cli-utils/src/issue.rs b/crates/turbopack-cli-utils/src/issue.rs index 34b589b58f900..df81ce39f86ad 100644 --- a/crates/turbopack-cli-utils/src/issue.rs +++ b/crates/turbopack-cli-utils/src/issue.rs @@ -79,13 +79,11 @@ fn severity_to_style(severity: IssueSeverity) -> Style { fn format_source_content(source: &PlainIssueSource, formatted_issue: &mut String) { if let FileLinesContent::Lines(lines) = source.asset.content.lines_ref() { - let start_line = source.start.line; - let end_line = source.end.line; - let start_column = source.start.column; - let end_column = source.end.column; - let lines = lines.iter().map(|l| l.content.as_str()); - let ctx = get_source_context(lines, start_line, start_column, end_line, end_column); - format_source_context_lines(&ctx, formatted_issue); + if let Some((start, end)) = source.range { + let lines = lines.iter().map(|l| l.content.as_str()); + let ctx = get_source_context(lines, start.line, start.column, end.line, end.column); + format_source_context_lines(&ctx, formatted_issue); + } } } @@ -143,23 +141,8 @@ pub fn format_issue( .replace("/./", "/") .replace("\\\\?\\", ""); let category = &plain_issue.category; - let title = &plain_issue.title; - - let mut styled_issue = if let Some(source) = &plain_issue.source { - let mut styled_issue = format!( - "{}:{}:{} {}", - context_path, - source.start.line + 1, - source.start.column, - title.bold() - ); - styled_issue.push('\n'); - format_source_content(source, &mut styled_issue); - styled_issue - } else { - format!("{}", title.bold()) - }; + let mut styled_issue = style_issue_source(plain_issue, &context_path); let description = &plain_issue.description; if !description.is_empty() { writeln!(styled_issue, "\n{description}").unwrap(); @@ -395,27 +378,12 @@ impl IssueReporter for ConsoleUi { let context_path = make_relative_to_cwd(&plain_issue.file_path, project_dir, current_dir); let category = &plain_issue.category; - let title = &plain_issue.title; let processing_path = &*plain_issue.processing_path; let severity_map = grouped_issues.entry(severity).or_default(); let category_map = severity_map.entry(category.clone()).or_default(); let issues = category_map.entry(context_path.to_string()).or_default(); - let mut styled_issue = if let Some(source) = &plain_issue.source { - let mut styled_issue = format!( - "{}:{}:{} {}", - context_path, - source.start.line + 1, - source.start.column, - title.bold() - ); - styled_issue.push('\n'); - format_source_content(source, &mut styled_issue); - styled_issue - } else { - format!("{}", title.bold()) - }; - + let mut styled_issue = style_issue_source(&plain_issue, &context_path); let description = &plain_issue.description; if !description.is_empty() { writeln!(&mut styled_issue, "\n{description}")?; @@ -570,3 +538,25 @@ fn show_all_message_with_shown_count( .bold() } } + +fn style_issue_source(plain_issue: &PlainIssue, context_path: &str) -> String { + let title = &plain_issue.title; + + if let Some(source) = &plain_issue.source { + let mut styled_issue = match source.range { + Some((start, _)) => format!( + "{}:{}:{} {}", + context_path, + start.line + 1, + start.column, + title.bold() + ), + None => format!("{} {}", context_path, title.bold()), + }; + styled_issue.push('\n'); + format_source_content(source, &mut styled_issue); + styled_issue + } else { + format!("{}", title.bold()) + } +} diff --git a/crates/turbopack-core/src/issue/mod.rs b/crates/turbopack-core/src/issue/mod.rs index 2fe651f0025a5..6c21ad227c698 100644 --- a/crates/turbopack-core/src/issue/mod.rs +++ b/crates/turbopack-core/src/issue/mod.rs @@ -4,7 +4,7 @@ pub mod resolve; pub mod unsupported_module; use std::{ - cmp::Ordering, + cmp::{min, Ordering}, fmt::{Display, Formatter}, sync::Arc, }; @@ -404,25 +404,49 @@ impl CapturedIssues { #[derive(Clone, Debug)] pub struct LazyIssueSource { pub source: Vc>, - pub start: usize, - pub end: usize, + pub start_end: Option<(usize, usize)>, } #[turbo_tasks::value_impl] impl LazyIssueSource { + /// Create a [`LazyIssueSource`] from byte offsets given by an swc ast node + /// span. + /// + /// Arguments: + /// + /// * `source`: The source code in which to look up the byte offsets. + /// * `start`: The start index of the span. Must use **1-based** indexing. + /// * `end`: The end index of the span. Must use **1-based** indexing. #[turbo_tasks::function] - pub fn new(source: Vc>, start: usize, end: usize) -> Vc { - Self::cell(LazyIssueSource { source, start, end }) + pub fn from_swc_offsets(source: Vc>, start: usize, end: usize) -> Vc { + match (start == 0, end == 0) { + (true, true) => Self::cell(LazyIssueSource { + source, + start_end: None, + }), + (false, false) => Self::cell(LazyIssueSource { + source, + start_end: Some((start - 1, end - 1)), + }), + (false, true) => Self::cell(LazyIssueSource { + source, + start_end: Some((start - 1, start - 1)), + }), + (true, false) => Self::cell(LazyIssueSource { + source, + start_end: Some((end - 1, end - 1)), + }), + } } #[turbo_tasks::function] pub async fn to_issue_source(self: Vc) -> Result> { let this = &*self.await?; - Ok(IssueSource::from_byte_offset( - this.source, - this.start, - this.end, - )) + Ok(if let Some((start, end)) = this.start_end { + IssueSource::from_byte_offset(this.source, start, end) + } else { + IssueSource::from_source_only(this.source) + }) } } @@ -430,13 +454,33 @@ impl LazyIssueSource { #[derive(Clone, Debug)] pub struct IssueSource { source: Vc>, - start: SourcePos, - end: SourcePos, + range: Option<(SourcePos, SourcePos)>, } #[turbo_tasks::value_impl] impl IssueSource { + // Sometimes we only have the source file that causes an issue, not the + // exact location, such as as in some generated code. + #[turbo_tasks::function] + pub fn from_source_only(source: Vc>) -> Vc { + Self::cell(IssueSource { + source, + range: None, + }) + } + #[turbo_tasks::function] + /// Returns an `IssueSource` representing a span of code in the `source`. + /// Positions are derived from byte offsets and stored as lines and columns. + /// Requires a binary search of the source text to perform this. + /// + /// Arguments: + /// + /// * `source`: The source code in which to look up the byte offsets. + /// * `start`: Byte offset into the source that the text begins. 0-based + /// index and inclusive. + /// * `end`: Byte offset into the source that the text ends. 0-based index + /// and exclusive. pub async fn from_byte_offset( source: Vc>, start: usize, @@ -452,27 +496,25 @@ impl IssueSource { column: offset, } } else { + let line = &lines[i - 1]; SourcePos { line: i - 1, - column: offset - lines[i - 1].bytes_offset, + column: min(line.content.len(), offset - line.bytes_offset), } } } } } - Ok(Self::cell( - if let FileLinesContent::Lines(lines) = &*source.content().lines().await? { + Ok(Self::cell(IssueSource { + source, + range: if let FileLinesContent::Lines(lines) = &*source.content().lines().await? { let start = find_line_and_column(lines.as_ref(), start); let end = find_line_and_column(lines.as_ref(), end); - IssueSource { source, start, end } + Some((start, end)) } else { - IssueSource { - source, - start: SourcePos::default(), - end: SourcePos::max(), - } + None }, - )) + })) } } @@ -512,8 +554,7 @@ fn hash_plain_issue(issue: &PlainIssue, hasher: &mut Xxh3Hash64Hasher, full: boo hasher.write_value(1_u8); // I'm assuming we don't need to hash the contents. Not 100% correct, but // probably 99%. - hasher.write_ref(&source.start); - hasher.write_ref(&source.end); + hasher.write_ref(&source.range); } else { hasher.write_value(0_u8); } @@ -564,8 +605,7 @@ impl PlainIssue { #[derive(Clone, Debug)] pub struct PlainIssueSource { pub asset: ReadRef, - pub start: SourcePos, - pub end: SourcePos, + pub range: Option<(SourcePos, SourcePos)>, } #[turbo_tasks::value_impl] @@ -575,8 +615,7 @@ impl IssueSource { let this = self.await?; Ok(PlainIssueSource { asset: PlainSource::from_source(this.source).await?, - start: this.start, - end: this.end, + range: this.range, } .cell()) } diff --git a/crates/turbopack-core/src/source_pos.rs b/crates/turbopack-core/src/source_pos.rs index 0b55d8e7e871e..85ce66757b72e 100644 --- a/crates/turbopack-core/src/source_pos.rs +++ b/crates/turbopack-core/src/source_pos.rs @@ -22,7 +22,9 @@ const U8_CR: u8 = 0x0D; DeterministicHash, )] pub struct SourcePos { + /// The line, 0-indexed. pub line: usize, + /// The byte index of the column, 0-indexed. pub column: usize, } diff --git a/crates/turbopack-css/src/references/mod.rs b/crates/turbopack-css/src/references/mod.rs index e76e25292483b..0c9672f3debf9 100644 --- a/crates/turbopack-css/src/references/mod.rs +++ b/crates/turbopack-css/src/references/mod.rs @@ -133,7 +133,7 @@ impl<'a> VisitAstPath for ModuleReferencesVisitor<'a> { Request::parse(Value::new(src.to_string().into())), Vc::cell(as_parent_path(ast_path)), ImportAttributes::new_from_prelude(i).into(), - LazyIssueSource::new( + LazyIssueSource::from_swc_offsets( Vc::upcast(self.source), issue_span.lo.to_usize(), issue_span.hi.to_usize(), @@ -160,7 +160,7 @@ impl<'a> VisitAstPath for ModuleReferencesVisitor<'a> { self.origin, Request::parse(Value::new(src.to_string().into())), Vc::cell(as_parent_path(ast_path)), - LazyIssueSource::new( + LazyIssueSource::from_swc_offsets( Vc::upcast(self.source), issue_span.lo.to_usize(), issue_span.hi.to_usize(), diff --git a/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs b/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs index d5067b6a193fd..1fb043bd93a28 100644 --- a/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs +++ b/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs @@ -124,6 +124,11 @@ pub struct Asset<'a> { #[derive(Serialize)] pub struct IssueSource<'a> { pub asset: Asset<'a>, + pub range: Option, +} + +#[derive(Serialize)] +pub struct IssueSourceRange { pub start: SourcePos, pub end: SourcePos, } @@ -151,8 +156,9 @@ impl<'a> From<&'a PlainIssue> for Issue<'a> { asset: Asset { path: &source.asset.ident, }, - start: source.start, - end: source.end, + range: source + .range + .map(|(start, end)| IssueSourceRange { start, end }), }); Issue { diff --git a/crates/turbopack-ecmascript-runtime/js/src/dev/runtime/base/protocol.d.ts b/crates/turbopack-ecmascript-runtime/js/src/dev/runtime/base/protocol.d.ts index a320d7245b820..7dadb227b27f5 100644 --- a/crates/turbopack-ecmascript-runtime/js/src/dev/runtime/base/protocol.d.ts +++ b/crates/turbopack-ecmascript-runtime/js/src/dev/runtime/base/protocol.d.ts @@ -124,6 +124,10 @@ type SourcePos = { type IssueSource = { asset: IssueAsset; + range?: IssueSourceRange; +}; + +type IssueSourceRange = { start: SourcePos; end: SourcePos; }; diff --git a/crates/turbopack-ecmascript/benches/analyzer.rs b/crates/turbopack-ecmascript/benches/analyzer.rs index d17cbecf92083..d7e97abab698c 100644 --- a/crates/turbopack-ecmascript/benches/analyzer.rs +++ b/crates/turbopack-ecmascript/benches/analyzer.rs @@ -55,7 +55,7 @@ pub fn benchmark(c: &mut Criterion) { let top_level_mark = Mark::new(); program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); - let eval_context = EvalContext::new(&program, unresolved_mark); + let eval_context = EvalContext::new(&program, unresolved_mark, None); let var_graph = create_graph(&program, &eval_context); let input = BenchInput { diff --git a/crates/turbopack-ecmascript/src/analyzer/graph.rs b/crates/turbopack-ecmascript/src/analyzer/graph.rs index 2dafc012ebead..4800a5c3041f5 100644 --- a/crates/turbopack-ecmascript/src/analyzer/graph.rs +++ b/crates/turbopack-ecmascript/src/analyzer/graph.rs @@ -12,6 +12,8 @@ use swc_core::{ visit::{fields::*, VisitAstPath, VisitWithPath, *}, }, }; +use turbo_tasks::Vc; +use turbopack_core::source::Source; use super::{ConstantNumber, ConstantValue, ImportMap, JsValue, ObjectPart, WellKnownFunctionKind}; use crate::{analyzer::is_unresolved, utils::unparen}; @@ -263,10 +265,14 @@ pub struct EvalContext { } impl EvalContext { - pub fn new(module: &Program, unresolved_mark: Mark) -> Self { + pub fn new( + module: &Program, + unresolved_mark: Mark, + source: Option>>, + ) -> Self { Self { unresolved_mark, - imports: ImportMap::analyze(module), + imports: ImportMap::analyze(module, source), } } diff --git a/crates/turbopack-ecmascript/src/analyzer/imports.rs b/crates/turbopack-ecmascript/src/analyzer/imports.rs index 5d67cc1aece1a..5c852b654d88d 100644 --- a/crates/turbopack-ecmascript/src/analyzer/imports.rs +++ b/crates/turbopack-ecmascript/src/analyzer/imports.rs @@ -2,11 +2,16 @@ use std::{collections::BTreeMap, fmt::Display, mem::take}; use indexmap::{IndexMap, IndexSet}; use once_cell::sync::Lazy; -use swc_core::ecma::{ - ast::*, - atoms::{js_word, JsWord}, - visit::{Visit, VisitWith}, +use swc_core::{ + common::{source_map::Pos, Span}, + ecma::{ + ast::*, + atoms::{js_word, JsWord}, + visit::{Visit, VisitWith}, + }, }; +use turbo_tasks::Vc; +use turbopack_core::{issue::LazyIssueSource, source::Source}; use super::{JsValue, ModuleValue}; use crate::utils::unparen; @@ -81,7 +86,7 @@ pub(crate) enum Reexport { /// The storage for all kinds of imports. /// -/// Note that wHen it's initialized by calling `analyze`, it only contains ESM +/// Note that when it's initialized by calling `analyze`, it only contains ESM /// import/exports. #[derive(Default, Debug)] pub(crate) struct ImportMap { @@ -113,6 +118,7 @@ pub(crate) struct ImportMapReference { pub module_path: JsWord, pub imported_symbol: ImportedSymbol, pub annotations: ImportAnnotations, + pub issue_source: Option>, } impl ImportMap { @@ -161,12 +167,13 @@ impl ImportMap { } /// Analyze ES import - pub(super) fn analyze(m: &Program) -> Self { + pub(super) fn analyze(m: &Program, source: Option>>) -> Self { let mut data = ImportMap::default(); m.visit_with(&mut Analyzer { data: &mut data, current_annotations: ImportAnnotations::default(), + source, }); data @@ -176,18 +183,25 @@ impl ImportMap { struct Analyzer<'a> { data: &'a mut ImportMap, current_annotations: ImportAnnotations, + source: Option>>, } impl<'a> Analyzer<'a> { fn ensure_reference( &mut self, + span: Span, module_path: JsWord, imported_symbol: ImportedSymbol, annotations: ImportAnnotations, ) -> usize { + let issue_source = self + .source + .map(|s| LazyIssueSource::from_swc_offsets(s, span.lo.to_usize(), span.hi.to_usize())); + let r = ImportMapReference { module_path, imported_symbol, + issue_source, annotations, }; if let Some(i) = self.data.references.get_index_of(&r) { @@ -244,8 +258,8 @@ impl Visit for Analyzer<'_> { fn visit_import_decl(&mut self, import: &ImportDecl) { let annotations = take(&mut self.current_annotations); - self.ensure_reference( + import.span, import.src.value.clone(), ImportedSymbol::ModuleEvaluation, annotations.clone(), @@ -253,7 +267,12 @@ impl Visit for Analyzer<'_> { for s in &import.specifiers { let symbol = get_import_symbol_from_import(s); - let i = self.ensure_reference(import.src.value.clone(), symbol, annotations.clone()); + let i = self.ensure_reference( + import.span, + import.src.value.clone(), + symbol, + annotations.clone(), + ); let (local, orig_sym) = match s { ImportSpecifier::Named(ImportNamedSpecifier { @@ -278,11 +297,13 @@ impl Visit for Analyzer<'_> { let annotations = take(&mut self.current_annotations); self.ensure_reference( + export.span, export.src.value.clone(), ImportedSymbol::ModuleEvaluation, annotations.clone(), ); let i = self.ensure_reference( + export.span, export.src.value.clone(), ImportedSymbol::Namespace, annotations, @@ -296,6 +317,7 @@ impl Visit for Analyzer<'_> { let annotations = take(&mut self.current_annotations); self.ensure_reference( + export.span, src.value.clone(), ImportedSymbol::ModuleEvaluation, annotations.clone(), @@ -304,7 +326,12 @@ impl Visit for Analyzer<'_> { for spec in export.specifiers.iter() { let symbol = get_import_symbol_from_export(spec); - let i = self.ensure_reference(src.value.clone(), symbol, annotations.clone()); + let i = self.ensure_reference( + export.span, + src.value.clone(), + symbol, + annotations.clone(), + ); match spec { ExportSpecifier::Namespace(n) => { diff --git a/crates/turbopack-ecmascript/src/analyzer/mod.rs b/crates/turbopack-ecmascript/src/analyzer/mod.rs index 99a5e9e703d45..ffd2a623419c2 100644 --- a/crates/turbopack-ecmascript/src/analyzer/mod.rs +++ b/crates/turbopack-ecmascript/src/analyzer/mod.rs @@ -3298,7 +3298,7 @@ mod tests { let top_level_mark = Mark::new(); m.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); - let eval_context = EvalContext::new(&m, unresolved_mark); + let eval_context = EvalContext::new(&m, unresolved_mark, None); let mut var_graph = create_graph(&m, &eval_context); diff --git a/crates/turbopack-ecmascript/src/lib.rs b/crates/turbopack-ecmascript/src/lib.rs index db109b45ef914..b91ec93a1920b 100644 --- a/crates/turbopack-ecmascript/src/lib.rs +++ b/crates/turbopack-ecmascript/src/lib.rs @@ -271,6 +271,11 @@ impl EcmascriptModuleAsset { }) } + #[turbo_tasks::function] + pub async fn source(self: Vc) -> Result>> { + Ok(self.await?.source) + } + #[turbo_tasks::function] pub fn analyze(self: Vc) -> Vc { analyze_ecmascript_module(self, None) diff --git a/crates/turbopack-ecmascript/src/parse.rs b/crates/turbopack-ecmascript/src/parse.rs index 7219cc5d90e51..35c9c0f841a33 100644 --- a/crates/turbopack-ecmascript/src/parse.rs +++ b/crates/turbopack-ecmascript/src/parse.rs @@ -341,7 +341,7 @@ async fn parse_content( &mut swc_core::ecma::transforms::base::helpers::inject_helpers(unresolved_mark), ); - let eval_context = EvalContext::new(&parsed_program, unresolved_mark); + let eval_context = EvalContext::new(&parsed_program, unresolved_mark, Some(source)); Ok::(ParseResult::Ok { program: parsed_program, diff --git a/crates/turbopack-ecmascript/src/references/esm/base.rs b/crates/turbopack-ecmascript/src/references/esm/base.rs index ca6c057987a59..ea66adb034c0c 100644 --- a/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -11,7 +11,7 @@ use turbopack_core::{ ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, ChunkingTypeOption, ModuleId, }, - issue::IssueSeverity, + issue::{IssueSeverity, LazyIssueSource}, module::Module, reference::ModuleReference, reference_type::EcmaScriptModulesReferenceSubType, @@ -103,6 +103,7 @@ pub struct EsmAssetReference { pub origin: Vc>, pub request: Vc, pub annotations: ImportAnnotations, + pub issue_source: Option>, pub export_name: Option>, } @@ -126,12 +127,14 @@ impl EsmAssetReference { pub fn new( origin: Vc>, request: Vc, + issue_source: Option>, annotations: Value, export_name: Option>, ) -> Vc { Self::cell(EsmAssetReference { origin, request, + issue_source, annotations: annotations.into_value(), export_name, }) @@ -162,7 +165,7 @@ impl ModuleReference for EsmAssetReference { self.request, ty, IssueSeverity::Error.cell(), - None, + self.issue_source, )) } } diff --git a/crates/turbopack-ecmascript/src/references/mod.rs b/crates/turbopack-ecmascript/src/references/mod.rs index d37d1ee413373..1c6144f1e98d4 100644 --- a/crates/turbopack-ecmascript/src/references/mod.rs +++ b/crates/turbopack-ecmascript/src/references/mod.rs @@ -316,7 +316,7 @@ pub(crate) async fn analyze_ecmascript_module( let parsed = if let Some(part) = part { let parsed = parse(source, ty, transforms); - let split_data = split(path, parsed); + let split_data = split(path, source, parsed); part_of_module(split_data, part) } else { parse(source, ty, transforms) @@ -435,6 +435,7 @@ pub(crate) async fn analyze_ecmascript_module( let r = EsmAssetReference::new( origin, Request::parse(Value::new(r.module_path.to_string().into())), + r.issue_source, Value::new(r.annotations.clone()), if options.import_parts { match &r.imported_symbol { @@ -962,7 +963,11 @@ pub(crate) async fn analyze_ecmascript_module( Request::parse(Value::new(pat)), compile_time_info.environment().rendering(), Vc::cell(ast_path), - LazyIssueSource::new(source, span.lo.to_usize(), span.hi.to_usize()), + LazyIssueSource::from_swc_offsets( + source, + span.lo.to_usize(), + span.hi.to_usize(), + ), in_try, options .url_rewrite_behavior @@ -1759,6 +1764,11 @@ async fn handle_free_var_reference( )) }), Request::parse(Value::new(request.clone().into())), + Some(LazyIssueSource::from_swc_offsets( + state.source, + span.lo.to_usize(), + span.hi.to_usize(), + )), Default::default(), state .import_parts @@ -1783,7 +1793,7 @@ async fn handle_free_var_reference( } fn issue_source(source: Vc>, span: Span) -> Vc { - LazyIssueSource::new(source, span.lo.to_usize(), span.hi.to_usize()) + LazyIssueSource::from_swc_offsets(source, span.lo.to_usize(), span.hi.to_usize()) } fn analyze_amd_define( diff --git a/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/crates/turbopack-ecmascript/src/tree_shake/mod.rs index 8d43b2e03cdd2..4926ade127997 100644 --- a/crates/turbopack-ecmascript/src/tree_shake/mod.rs +++ b/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -4,7 +4,10 @@ use rustc_hash::FxHashMap; use swc_core::ecma::ast::{Id, Module, Program}; use turbo_tasks::Vc; use turbo_tasks_fs::FileSystemPath; -use turbopack_core::resolve::{origin::ResolveOrigin, ModulePart}; +use turbopack_core::{ + resolve::{origin::ResolveOrigin, ModulePart}, + source::Source, +}; use self::graph::{DepGraph, ItemData, ItemId, ItemIdGroupKind, Mode, SplitModuleResult}; use crate::{analyzer::graph::EvalContext, parse::ParseResult, EcmascriptModuleAsset}; @@ -296,12 +299,13 @@ impl PartialEq for SplitResult { #[turbo_tasks::function] pub(super) fn split_module(asset: Vc) -> Vc { - split(asset.origin_path(), asset.parse()) + split(asset.origin_path(), asset.source(), asset.parse()) } #[turbo_tasks::function] pub(super) async fn split( path: Vc, + source: Vc>, parsed: Vc, ) -> Result> { let filename = path.await?.file_name().to_string(); @@ -330,7 +334,8 @@ pub(super) async fn split( .into_iter() .map(|module| { let program = Program::Module(module); - let eval_context = EvalContext::new(&program, eval_context.unresolved_mark); + let eval_context = + EvalContext::new(&program, eval_context.unresolved_mark, Some(source)); ParseResult::cell(ParseResult::Ok { program, diff --git a/crates/turbopack-swc-utils/src/emitter.rs b/crates/turbopack-swc-utils/src/emitter.rs index 4f06fd9ab66f3..ac00ec12dc8fe 100644 --- a/crates/turbopack-swc-utils/src/emitter.rs +++ b/crates/turbopack-swc-utils/src/emitter.rs @@ -40,10 +40,9 @@ impl Emitter for IssueEmitter { message = message_split.remainder().unwrap_or("").to_string(); } - let source = db - .span - .primary_span() - .map(|span| LazyIssueSource::new(self.source, span.lo.to_usize(), span.hi.to_usize())); + let source = db.span.primary_span().map(|span| { + LazyIssueSource::from_swc_offsets(self.source, span.lo.to_usize(), span.hi.to_usize()) + }); // TODO add other primary and secondary spans with labels as sub_issues AnalyzeIssue { diff --git a/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-ee63e3.txt b/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-bd2850.txt similarity index 84% rename from crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-ee63e3.txt rename to crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-bd2850.txt index ce51578bb4a5e..f50d4f0056d24 100644 --- a/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-ee63e3.txt +++ b/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/Error resolving commonjs request-bd2850.txt @@ -1,10 +1,10 @@ -error - [resolve] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js /crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js:4:5 Error resolving commonjs request +error - [resolve] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js /crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js:4:4 Error resolving commonjs request 1 | it("importing a not existing file should throw", () => { 2 | // This is a check to make sure that the following tests would fail if they require("fail") 3 | expect(() => { - + v----------------------------v + + v----------------------------v 4 + require("./not-existing-file"); - + ^----------------------------^ + + ^----------------------------^ 5 | }).toThrow(); 6 | }); 7 | diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-b97684.txt b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-5da3a2.txt similarity index 79% rename from crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-b97684.txt rename to crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-5da3a2.txt index 3c8e795ebaed1..9b90dcaac01c7 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-b97684.txt +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/Error resolving commonjs request-5da3a2.txt @@ -1,7 +1,7 @@ -error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js /crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js:1:13 Error resolving commonjs request - + v----------------------------v +error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js /crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js:1:12 Error resolving commonjs request + + v----------------------------v 1 + const dne = require("does-not-exist/path"); - + ^----------------------------^ + + ^----------------------------^ 2 | 3 | console.log(dne); 4 | diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-aff400.txt b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-c6e3fb.txt similarity index 54% rename from crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-aff400.txt rename to crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-c6e3fb.txt index 1e1abc39b0f62..ed0d675e21566 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-aff400.txt +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/Error resolving EcmaScript Modules request-c6e3fb.txt @@ -1,4 +1,12 @@ -error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js Error resolving EcmaScript Modules request +error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js /crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js:1:0 Error resolving EcmaScript Modules request + + v------------------------------------v + 1 + import dne from "does-not-exist/path"; + + ^------------------------------------^ + 2 | + 3 | console.log(dne); + 4 | console.log({}[dne]); + 5 | + unable to resolve module "does-not-exist" with subpath "/path" | It was not possible to find the requested file.