Skip to main content

turbopack_core/issue/
analyze.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use turbo_rcstr::{RcStr, rcstr};
4use turbo_tasks::{ResolvedVc, Vc};
5use turbo_tasks_fs::FileSystemPath;
6
7use super::{AdditionalIssueSource, Issue, IssueSeverity, IssueSource, IssueStage, StyledString};
8use crate::ident::AssetIdent;
9
10#[turbo_tasks::value(shared)]
11pub struct AnalyzeIssue {
12    pub severity: IssueSeverity,
13    pub source_ident: ResolvedVc<AssetIdent>,
14    pub title: ResolvedVc<RcStr>,
15    pub message: ResolvedVc<StyledString>,
16    pub code: Option<RcStr>,
17    pub source: Option<IssueSource>,
18}
19
20#[turbo_tasks::value_impl]
21impl AnalyzeIssue {
22    #[turbo_tasks::function]
23    pub fn new(
24        severity: IssueSeverity,
25        source_ident: ResolvedVc<AssetIdent>,
26        title: ResolvedVc<RcStr>,
27        message: ResolvedVc<StyledString>,
28        code: Option<RcStr>,
29        source: Option<IssueSource>,
30    ) -> Vc<Self> {
31        Self {
32            severity,
33            source_ident,
34            title,
35            message,
36            code,
37            source,
38        }
39        .cell()
40    }
41}
42
43#[async_trait]
44#[turbo_tasks::value_impl]
45impl Issue for AnalyzeIssue {
46    fn severity(&self) -> IssueSeverity {
47        self.severity
48    }
49
50    async fn title(&self) -> Result<StyledString> {
51        let title = &*self.title.await?;
52        Ok(if let Some(code) = self.code.as_ref() {
53            StyledString::Line(vec![
54                StyledString::Strong(code.clone()),
55                StyledString::Text(rcstr!(" ")),
56                StyledString::Text(title.clone()),
57            ])
58        } else {
59            StyledString::Text(title.clone())
60        })
61    }
62
63    fn stage(&self) -> IssueStage {
64        IssueStage::Analysis
65    }
66
67    async fn file_path(&self) -> Result<FileSystemPath> {
68        Ok(self.source_ident.await?.path.clone())
69    }
70
71    async fn description(&self) -> Result<Option<StyledString>> {
72        Ok(Some((*self.message.await?).clone()))
73    }
74
75    fn source(&self) -> Option<IssueSource> {
76        self.source
77    }
78
79    async fn additional_sources(&self) -> Result<Vec<AdditionalIssueSource>> {
80        if let Some(issue_source) = self.source
81            && let Some(additional) = issue_source.to_generated_code_source().await?
82        {
83            return Ok(vec![additional]);
84        }
85        Ok(vec![])
86    }
87}