Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turbopack: make IssueSource a TaskInput #75542

Merged
merged 2 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/napi/src/next_api/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ impl From<&PlainIssue> for NapiIssue {
.map(|styled| serde_json::to_value(StyledStringSerialize::from(styled)).unwrap()),
documentation_link: issue.documentation_link.to_string(),
severity: issue.severity.as_str().to_string(),
source: issue.source.as_deref().map(|source| source.into()),
source: issue.source.as_ref().map(|source| source.into()),
title: serde_json::to_value(StyledStringSerialize::from(&issue.title)).unwrap(),
sub_issues: issue
.sub_issues
Expand Down
18 changes: 9 additions & 9 deletions crates/next-core/src/app_segment_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl NextSegmentConfig {
pub struct NextSegmentConfigParsingIssue {
ident: ResolvedVc<AssetIdent>,
detail: ResolvedVc<StyledString>,
source: ResolvedVc<IssueSource>,
source: IssueSource,
}

#[turbo_tasks::value_impl]
Expand All @@ -186,7 +186,7 @@ impl NextSegmentConfigParsingIssue {
pub fn new(
ident: ResolvedVc<AssetIdent>,
detail: ResolvedVc<StyledString>,
source: ResolvedVc<IssueSource>,
source: IssueSource,
) -> Vc<Self> {
Self {
ident,
Expand Down Expand Up @@ -249,15 +249,15 @@ impl Issue for NextSegmentConfigParsingIssue {
Ok(Vc::cell(Some(
self.source
.resolve_source_map(self.ident.path())
.to_resolved()
.await?,
.await?
.into_owned(),
)))
}
}

#[turbo_tasks::function]
pub async fn parse_segment_config_from_source(
source: Vc<Box<dyn Source>>,
source: ResolvedVc<Box<dyn Source>>,
) -> Result<Vc<NextSegmentConfig>> {
let path = source.ident().path().await?;

Expand All @@ -273,7 +273,7 @@ pub async fn parse_segment_config_from_source(
}

let result = &*parse(
source,
*source,
turbo_tasks::Value::new(if path.path.ends_with(".ts") {
EcmascriptModuleAssetType::Typescript {
tsx: false,
Expand Down Expand Up @@ -348,20 +348,20 @@ pub async fn parse_segment_config_from_source(
Ok(config.cell())
}

fn issue_source(source: Vc<Box<dyn Source>>, span: Span) -> Vc<IssueSource> {
fn issue_source(source: ResolvedVc<Box<dyn Source>>, span: Span) -> IssueSource {
IssueSource::from_swc_offsets(source, span.lo.to_usize(), span.hi.to_usize())
}

async fn parse_config_value(
source: Vc<Box<dyn Source>>,
source: ResolvedVc<Box<dyn Source>>,
config: &mut NextSegmentConfig,
ident: &Ident,
init: &Expr,
eval_context: &EvalContext,
) -> Result<()> {
let span = init.span();
async fn invalid_config(
source: Vc<Box<dyn Source>>,
source: ResolvedVc<Box<dyn Source>>,
span: Span,
detail: &str,
value: &JsValue,
Expand Down
10 changes: 5 additions & 5 deletions turbopack/crates/turbopack-core/src/issue/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct AnalyzeIssue {
pub title: ResolvedVc<RcStr>,
pub message: ResolvedVc<StyledString>,
pub code: Option<RcStr>,
pub source: Option<ResolvedVc<IssueSource>>,
pub source: Option<IssueSource>,
}

#[turbo_tasks::value_impl]
Expand All @@ -28,7 +28,7 @@ impl AnalyzeIssue {
title: ResolvedVc<RcStr>,
message: ResolvedVc<StyledString>,
code: Option<RcStr>,
source: Option<ResolvedVc<IssueSource>>,
source: Option<IssueSource>,
) -> Vc<Self> {
Self {
severity,
Expand Down Expand Up @@ -81,12 +81,12 @@ impl Issue for AnalyzeIssue {

#[turbo_tasks::function]
async fn source(&self) -> Result<Vc<OptionIssueSource>> {
Ok(Vc::cell(match self.source {
Ok(Vc::cell(match &self.source {
Some(source) => Some(
source
.resolve_source_map(self.source_ident.path())
.to_resolved()
.await?,
.await?
.into_owned(),
),
None => None,
}))
Expand Down
112 changes: 47 additions & 65 deletions turbopack/crates/turbopack-core/src/issue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ pub mod module;
pub mod resolve;

use std::{
borrow::Cow,
cmp::{min, Ordering},
fmt::{Display, Formatter},
};

use anyhow::{anyhow, Result};
use async_trait::async_trait;
use auto_hash_map::AutoSet;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use turbo_rcstr::RcStr;
use turbo_tasks::{
emit, CollectiblesSource, OperationVc, RawVc, ReadRef, ResolvedVc, TransientInstance,
TransientValue, TryJoinIterExt, Upcast, ValueToString, Vc,
emit, trace::TraceRawVcs, CollectiblesSource, NonLocalValue, OperationVc, RawVc, ReadRef,
ResolvedVc, TaskInput, TransientInstance, TransientValue, TryJoinIterExt, Upcast,
ValueToString, Vc,
};
use turbo_tasks_fs::{FileContent, FileLine, FileLinesContent, FileSystemPath};
use turbo_tasks_hash::{DeterministicHash, Xxh3Hash64Hasher};
Expand Down Expand Up @@ -172,7 +174,7 @@ pub trait Issue {
detail,
documentation_link: self.documentation_link().await?.clone_value(),
source: {
if let Some(s) = *self.source().await? {
if let Some(s) = &*self.source().await? {
Some(s.into_plain().await?)
} else {
None
Expand Down Expand Up @@ -435,79 +437,71 @@ impl CapturedIssues {
}
}

#[turbo_tasks::value]
#[derive(Clone, Debug)]
#[derive(
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, TaskInput, TraceRawVcs, NonLocalValue,
)]
pub struct IssueSource {
source: ResolvedVc<Box<dyn Source>>,
range: Option<ResolvedVc<SourceRange>>,
range: Option<SourceRange>,
}

/// The end position is the first character after the range
#[turbo_tasks::value]
#[derive(Clone, Debug)]
#[derive(
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, TaskInput, TraceRawVcs, NonLocalValue,
)]
enum SourceRange {
LineColumn(SourcePos, SourcePos),
ByteOffset(usize, usize),
}

#[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: ResolvedVc<Box<dyn Source>>) -> Vc<Self> {
Self::cell(IssueSource {
pub fn from_source_only(source: ResolvedVc<Box<dyn Source>>) -> Self {
IssueSource {
source,
range: None,
})
}
}

#[turbo_tasks::function]
pub fn from_line_col(
source: ResolvedVc<Box<dyn Source>>,
start: SourcePos,
end: SourcePos,
) -> Vc<Self> {
Self::cell(IssueSource {
) -> Self {
IssueSource {
source,
range: Some(SourceRange::LineColumn(start, end).resolved_cell()),
})
range: Some(SourceRange::LineColumn(start, end)),
}
}

#[turbo_tasks::function]
pub async fn resolve_source_map(
self: Vc<Self>,
origin: Vc<FileSystemPath>,
) -> Result<Vc<Self>> {
let this = self.await?;

if let Some(range) = this.range {
let (start, end) = match &*range.await? {
pub async fn resolve_source_map(&self, origin: Vc<FileSystemPath>) -> Result<Cow<'_, Self>> {
if let Some(range) = &self.range {
let (start, end) = match range {
SourceRange::LineColumn(start, end) => (*start, *end),

SourceRange::ByteOffset(start, end) => {
if let FileLinesContent::Lines(lines) = &*this.source.content().lines().await? {
if let FileLinesContent::Lines(lines) = &*self.source.content().lines().await? {
let start = find_line_and_column(lines.as_ref(), *start);
let end = find_line_and_column(lines.as_ref(), *end);
(start, end)
} else {
return Ok(self);
return Ok(Cow::Borrowed(self));
}
}
};

// If we have a source map, map the line/column to the original source.
let mapped = source_pos(this.source, origin, start, end).await?;
let mapped = source_pos(self.source, origin, start, end).await?;

if let Some((source, start, end)) = mapped {
return Ok(Self::cell(IssueSource {
return Ok(Cow::Owned(IssueSource {
source,
range: Some(SourceRange::LineColumn(start, end).resolved_cell()),
range: Some(SourceRange::LineColumn(start, end)),
}));
}
}

Ok(self)
Ok(Cow::Borrowed(self))
}

/// Create a [`IssueSource`] from byte offsets given by an swc ast node
Expand All @@ -518,26 +512,18 @@ impl IssueSource {
/// * `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 from_swc_offsets(
source: ResolvedVc<Box<dyn Source>>,
start: usize,
end: usize,
) -> Vc<Self> {
Self::cell(IssueSource {
pub fn from_swc_offsets(source: ResolvedVc<Box<dyn Source>>, start: usize, end: usize) -> Self {
IssueSource {
source,
range: match (start == 0, end == 0) {
(true, true) => None,
(false, false) => Some(SourceRange::ByteOffset(start - 1, end - 1).resolved_cell()),
(false, true) => {
Some(SourceRange::ByteOffset(start - 1, start - 1).resolved_cell())
}
(true, false) => Some(SourceRange::ByteOffset(end - 1, end - 1).resolved_cell()),
(false, false) => Some(SourceRange::ByteOffset(start - 1, end - 1)),
(false, true) => Some(SourceRange::ByteOffset(start - 1, start - 1)),
(true, false) => Some(SourceRange::ByteOffset(end - 1, end - 1)),
},
})
}
}

#[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.
Expand All @@ -551,21 +537,20 @@ impl IssueSource {
source: ResolvedVc<Box<dyn Source>>,
start: usize,
end: usize,
) -> Result<Vc<Self>> {
Ok(Self::cell(IssueSource {
) -> Result<Self> {
Ok(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);
Some(SourceRange::LineColumn(start, end).resolved_cell())
Some(SourceRange::LineColumn(start, end))
} else {
None
},
}))
})
}

/// Returns the file path for the source file.
#[turbo_tasks::function]
pub fn file_path(&self) -> Vc<FileSystemPath> {
self.source.ident().path()
}
Expand All @@ -574,8 +559,8 @@ impl IssueSource {
impl IssueSource {
/// Returns bytes offsets corresponding the source range in the format used by swc's Spans.
pub async fn to_swc_offsets(&self) -> Result<Option<(usize, usize)>> {
Ok(match self.range {
Some(range) => match &*range.await? {
Ok(match &self.range {
Some(range) => match range {
SourceRange::ByteOffset(start, end) => Some((*start + 1, *end + 1)),
SourceRange::LineColumn(start, end) => {
if let FileLinesContent::Lines(lines) = &*self.source.content().lines().await? {
Expand Down Expand Up @@ -647,7 +632,7 @@ async fn source_pos(
}

#[turbo_tasks::value(transparent)]
pub struct OptionIssueSource(Option<ResolvedVc<IssueSource>>);
pub struct OptionIssueSource(Option<IssueSource>);

#[turbo_tasks::value(transparent)]
pub struct OptionStyledString(Option<ResolvedVc<StyledString>>);
Expand Down Expand Up @@ -707,7 +692,7 @@ pub struct PlainIssue {
pub detail: Option<StyledString>,
pub documentation_link: RcStr,

pub source: Option<ReadRef<PlainIssueSource>>,
pub source: Option<PlainIssueSource>,
pub sub_issues: Vec<ReadRef<PlainIssue>>,
pub processing_path: ReadRef<PlainIssueProcessingPath>,
}
Expand Down Expand Up @@ -779,14 +764,12 @@ pub struct PlainIssueSource {
pub range: Option<(SourcePos, SourcePos)>,
}

#[turbo_tasks::value_impl]
impl IssueSource {
#[turbo_tasks::function]
pub async fn into_plain(&self) -> Result<Vc<PlainIssueSource>> {
pub async fn into_plain(&self) -> Result<PlainIssueSource> {
Ok(PlainIssueSource {
asset: PlainSource::from_source(*self.source).await?,
range: match self.range {
Some(range) => match &*range.await? {
range: match &self.range {
Some(range) => match range {
SourceRange::LineColumn(start, end) => Some((*start, *end)),
SourceRange::ByteOffset(start, end) => {
if let FileLinesContent::Lines(lines) =
Expand All @@ -802,8 +785,7 @@ impl IssueSource {
},
_ => None,
},
}
.cell())
})
}
}

Expand Down
8 changes: 4 additions & 4 deletions turbopack/crates/turbopack-core/src/issue/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct ResolvingIssue {
pub file_path: ResolvedVc<FileSystemPath>,
pub resolve_options: ResolvedVc<ResolveOptions>,
pub error_message: Option<String>,
pub source: Option<ResolvedVc<IssueSource>>,
pub source: Option<IssueSource>,
}

#[turbo_tasks::value_impl]
Expand Down Expand Up @@ -122,12 +122,12 @@ impl Issue for ResolvingIssue {

#[turbo_tasks::function]
async fn source(&self) -> Result<Vc<OptionIssueSource>> {
Ok(Vc::cell(match self.source {
Ok(Vc::cell(match &self.source {
Some(source) => Some(
source
.resolve_source_map(*self.file_path)
.to_resolved()
.await?,
.await?
.into_owned(),
),
None => None,
}))
Expand Down
Loading
Loading