naga/front/wgsl/parse/
directive.rs1pub mod enable_extension;
6pub(crate) mod language_extension;
7
8use alloc::boxed::Box;
9
10#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
12#[cfg_attr(test, derive(strum::EnumIter))]
13pub(crate) enum DirectiveKind {
14    Diagnostic,
16    Enable,
18    Requires,
20}
21
22impl DirectiveKind {
23    const DIAGNOSTIC: &'static str = "diagnostic";
24    const ENABLE: &'static str = "enable";
25    const REQUIRES: &'static str = "requires";
26
27    pub fn from_ident(s: &str) -> Option<Self> {
29        Some(match s {
30            Self::DIAGNOSTIC => Self::Diagnostic,
31            Self::ENABLE => Self::Enable,
32            Self::REQUIRES => Self::Requires,
33            _ => return None,
34        })
35    }
36}
37
38impl crate::diagnostic_filter::Severity {
39    #[cfg(feature = "wgsl-in")]
40    pub(crate) fn report_wgsl_parse_diag<'a>(
41        self,
42        err: Box<crate::front::wgsl::error::Error<'a>>,
43        source: &str,
44    ) -> crate::front::wgsl::Result<'a, ()> {
45        self.report_diag(err, |e, level| {
46            let e = e.as_parse_error(source);
47            log::log!(level, "{}", e.emit_to_string(source));
48        })
49    }
50}
51
52#[cfg(test)]
53mod test {
54    use alloc::format;
55
56    use strum::IntoEnumIterator;
57
58    use super::DirectiveKind;
59    use crate::front::wgsl::assert_parse_err;
60
61    #[test]
62    fn directive_after_global_decl() {
63        for unsupported_shader in DirectiveKind::iter() {
64            let directive;
65            let expected_msg;
66            match unsupported_shader {
67                DirectiveKind::Diagnostic => {
68                    directive = "diagnostic(off,derivative_uniformity)";
69                    expected_msg = "\
70error: expected global declaration, but found a global directive
71  ┌─ wgsl:2:1
72  │
732 │ diagnostic(off,derivative_uniformity);
74  │ ^^^^^^^^^^ written after first global declaration
75  │
76  = note: global directives are only allowed before global declarations; maybe hoist this closer to the top of the shader module?
77
78";
79                }
80                DirectiveKind::Enable => {
81                    directive = "enable f16";
82                    expected_msg = "\
83error: expected global declaration, but found a global directive
84  ┌─ wgsl:2:1
85  │
862 │ enable f16;
87  │ ^^^^^^ written after first global declaration
88  │
89  = note: global directives are only allowed before global declarations; maybe hoist this closer to the top of the shader module?
90
91";
92                }
93                DirectiveKind::Requires => {
94                    directive = "requires readonly_and_readwrite_storage_textures";
95                    expected_msg = "\
96error: expected global declaration, but found a global directive
97  ┌─ wgsl:2:1
98  │
992 │ requires readonly_and_readwrite_storage_textures;
100  │ ^^^^^^^^ written after first global declaration
101  │
102  = note: global directives are only allowed before global declarations; maybe hoist this closer to the top of the shader module?
103
104";
105                }
106            }
107
108            let shader = format!(
109                "\
110@group(0) @binding(0) var<storage> thing: i32;
111{directive};
112"
113            );
114            assert_parse_err(&shader, expected_msg);
115        }
116    }
117}