turbopack_core/
context.rs

1use anyhow::{Result, bail};
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::{FileSystemPath, glob::Glob};
5
6use crate::{
7    compile_time_info::CompileTimeInfo,
8    ident::Layer,
9    issue::module::emit_unknown_module_type_error,
10    module::{Module, OptionModule},
11    reference_type::ReferenceType,
12    resolve::{ModuleResolveResult, ResolveResult, options::ResolveOptions, parse::Request},
13    source::Source,
14};
15
16#[turbo_tasks::value(shared)]
17pub enum ProcessResult {
18    /// A module was created.
19    Module(ResolvedVc<Box<dyn Module>>),
20
21    /// A module could not be created (according to the rules, e.g. no module type was assigned)
22    Unknown(ResolvedVc<Box<dyn Source>>),
23
24    /// Reference is ignored. This should lead to no module being included by
25    /// the reference.
26    Ignore,
27}
28
29#[turbo_tasks::value_impl]
30impl ProcessResult {
31    #[turbo_tasks::function]
32    pub fn module(&self) -> Result<Vc<Box<dyn Module>>> {
33        match *self {
34            ProcessResult::Module(m) => Ok(*m),
35            ProcessResult::Ignore => {
36                bail!("Expected process result to be a module, but it was ignored")
37            }
38            ProcessResult::Unknown(_) => {
39                bail!("Expected process result to be a module, but it could not be processed")
40            }
41        }
42    }
43
44    /// Unwrap the module, or return None and emit an issue
45    #[turbo_tasks::function]
46    pub async fn try_into_module(&self) -> Result<Vc<OptionModule>> {
47        Ok(Vc::cell(match self {
48            ProcessResult::Module(module) => Some(*module),
49            ProcessResult::Unknown(source) => {
50                emit_unknown_module_type_error(**source).await?;
51                None
52            }
53            ProcessResult::Ignore => None,
54        }))
55    }
56}
57
58/// A context for building an asset graph. It's passed through the assets while
59/// creating them. It's needed to resolve assets and upgrade assets to a higher
60/// type (e. g. from FileSource to ModuleAsset).
61#[turbo_tasks::value_trait]
62pub trait AssetContext {
63    /// Gets the compile time info of the asset context.
64    #[turbo_tasks::function]
65    fn compile_time_info(self: Vc<Self>) -> Vc<CompileTimeInfo>;
66
67    /// Gets the layer of the asset context.
68    fn layer(&self) -> Layer;
69
70    /// Gets the resolve options for a given path.
71    #[turbo_tasks::function]
72    fn resolve_options(
73        self: Vc<Self>,
74        origin_path: FileSystemPath,
75        reference_type: ReferenceType,
76    ) -> Vc<ResolveOptions>;
77
78    /// Resolves an request to an [ModuleResolveResult].
79    #[turbo_tasks::function]
80    fn resolve_asset(
81        self: Vc<Self>,
82        origin_path: FileSystemPath,
83        request: Vc<Request>,
84        resolve_options: Vc<ResolveOptions>,
85        reference_type: ReferenceType,
86    ) -> Vc<ModuleResolveResult>;
87
88    /// Process a source into a module.
89    #[turbo_tasks::function]
90    fn process(
91        self: Vc<Self>,
92        asset: Vc<Box<dyn Source>>,
93        reference_type: ReferenceType,
94    ) -> Vc<ProcessResult>;
95
96    /// Process an [ResolveResult] into an [ModuleResolveResult].
97    #[turbo_tasks::function]
98    fn process_resolve_result(
99        self: Vc<Self>,
100        result: Vc<ResolveResult>,
101        reference_type: ReferenceType,
102    ) -> Vc<ModuleResolveResult>;
103
104    /// Gets a new AssetContext with the transition applied.
105    #[turbo_tasks::function]
106    fn with_transition(self: Vc<Self>, transition: RcStr) -> Vc<Box<dyn AssetContext>>;
107
108    #[turbo_tasks::function]
109    fn side_effect_free_packages(self: Vc<Self>) -> Vc<Glob>;
110}