Skip to main content

wesl/pass/
link.rs

1use wgsl_parse::{SyntaxNode, syntax::TranslationUnit};
2
3use crate::pass::{self, Module, UsedItems};
4
5/// Merge all declarations into a single module.
6///
7/// If `used_items` is set, the final module includes only used items. Otherwise, it
8/// includes all declarations.
9pub fn link(modules: &[Module], used_items: Option<&UsedItems>) -> TranslationUnit {
10    let mut result = TranslationUnit::default();
11    for module in modules {
12        if let Some(used_items) = &used_items {
13            result.global_declarations.extend(
14                module
15                    .syntax
16                    .global_declarations
17                    .iter()
18                    .filter(|decl| {
19                        decl.is_const_assert()
20                            || decl
21                                .ident()
22                                .is_some_and(|id| used_items.get_ident(&module.path, &id).is_some())
23                    })
24                    .cloned(),
25            );
26        } else {
27            result
28                .global_declarations
29                .extend(module.syntax.global_declarations.clone());
30        }
31        result
32            .global_directives
33            .extend(module.syntax.global_directives.clone());
34    }
35
36    pass::strip_visibility(&mut result);
37
38    // TODO: <https://github.com/webgpu-tools/wesl-spec/issues/71>
39    // currently the behavior is:
40    // * include all directives used (if strip)
41    // * include all directives (if not strip)
42    result.global_directives.dedup();
43
44    result
45}