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: RcStr,
15    pub message: RcStr,
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: RcStr,
27        message: RcStr,
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        Ok(if let Some(code) = self.code.as_ref() {
52            StyledString::Line(vec![
53                StyledString::Strong(code.clone()),
54                StyledString::Text(rcstr!(" ")),
55                StyledString::Text(self.title.clone()),
56            ])
57        } else {
58            StyledString::Text(self.title.clone())
59        })
60    }
61
62    fn stage(&self) -> IssueStage {
63        IssueStage::Analysis
64    }
65
66    async fn file_path(&self) -> Result<FileSystemPath> {
67        Ok(self.source_ident.await?.path.clone())
68    }
69
70    async fn description(&self) -> Result<Option<StyledString>> {
71        Ok(Some(StyledString::Text(self.message.clone())))
72    }
73
74    fn source(&self) -> Option<IssueSource> {
75        self.source
76    }
77
78    async fn additional_sources(&self) -> Result<Vec<AdditionalIssueSource>> {
79        if let Some(issue_source) = self.source
80            && let Some(additional) = issue_source.to_generated_code_source().await?
81        {
82            return Ok(vec![additional]);
83        }
84        Ok(vec![])
85    }
86}