Skip to content

Commit 28af245

Browse files
Vrixyzteoxoy
andauthored
[wgsl-in,ir] Add support for parsing rust-style doc comments (#6364)
* [wgsl-in,ir] add support for parsing rust-style doc comments * rename relevant items to `doc_comments` (or variations of it) * address comments * remove `next_until` * rename `save_doc_comments` to `ignore_doc_comments` * expand snapshot test and ignore blankspace when accumulating doc comments * make tokenizer more straightforward --------- Co-authored-by: teoxoy <28601907+teoxoy@users.noreply.github.com>
1 parent 00bc80d commit 28af245

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+964
-30
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Bottom level categories:
4545
#### Naga
4646

4747
- Added `no_std` support with default features disabled. By @Bushrat011899 in [#7585](https://github.com/gfx-rs/wgpu/pull/7585).
48+
- [wgsl-in,ir] Add support for parsing rust-style doc comments via `naga::front::glsl::Frontend::new_with_options`. By @Vrixyz in [#6364](https://github.com/gfx-rs/wgpu/pull/6364).
4849

4950
#### General
5051

naga/src/compact/mod.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,42 @@ pub fn compact(module: &mut crate::Module) {
272272
module_map.global_expressions.adjust(init);
273273
}
274274
}
275+
// Adjust doc comments
276+
if let Some(ref mut doc_comments) = module.doc_comments {
277+
let crate::DocComments {
278+
module: _,
279+
types: ref mut doc_comments_for_types,
280+
struct_members: ref mut doc_comments_for_struct_members,
281+
entry_points: _,
282+
functions: _,
283+
constants: ref mut doc_comments_for_constants,
284+
global_variables: _,
285+
} = **doc_comments;
286+
log::trace!("adjusting doc comments for types");
287+
for (mut ty, doc_comment) in core::mem::take(doc_comments_for_types) {
288+
if !module_map.types.used(ty) {
289+
continue;
290+
}
291+
module_map.types.adjust(&mut ty);
292+
doc_comments_for_types.insert(ty, doc_comment);
293+
}
294+
log::trace!("adjusting doc comments for struct members");
295+
for ((mut ty, index), doc_comment) in core::mem::take(doc_comments_for_struct_members) {
296+
if !module_map.types.used(ty) {
297+
continue;
298+
}
299+
module_map.types.adjust(&mut ty);
300+
doc_comments_for_struct_members.insert((ty, index), doc_comment);
301+
}
302+
log::trace!("adjusting doc comments for constants");
303+
for (mut constant, doc_comment) in core::mem::take(doc_comments_for_constants) {
304+
if !module_map.constants.used(constant) {
305+
continue;
306+
}
307+
module_map.constants.adjust(&mut constant);
308+
doc_comments_for_constants.insert(constant, doc_comment);
309+
}
310+
}
275311

276312
// Temporary storage to help us reuse allocations of existing
277313
// named expression tables.

naga/src/front/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub mod spv;
1414
#[cfg(feature = "wgsl-in")]
1515
pub mod wgsl;
1616

17-
use alloc::{vec, vec::Vec};
17+
use alloc::{boxed::Box, vec, vec::Vec};
1818
use core::ops;
1919

2020
use crate::{
@@ -330,3 +330,10 @@ impl<Name: fmt::Debug, Var: fmt::Debug> fmt::Debug for SymbolTable<Name, Var> {
330330
.finish()
331331
}
332332
}
333+
334+
impl crate::Module {
335+
pub fn get_or_insert_default_doc_comments(&mut self) -> &mut Box<crate::DocComments> {
336+
self.doc_comments
337+
.get_or_insert_with(|| Box::new(crate::DocComments::default()))
338+
}
339+
}

naga/src/front/wgsl/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ impl<'a> Error<'a> {
469469
Token::Arrow => "->".to_string(),
470470
Token::Unknown(c) => format!("unknown (`{c}`)"),
471471
Token::Trivia => "trivia".to_string(),
472+
Token::DocComment(s) => format!("doc comment ('{s}')"),
473+
Token::ModuleDocComment(s) => format!("module doc comment ('{s}')"),
472474
Token::End => "end".to_string(),
473475
},
474476
ExpectedToken::Identifier => "identifier".to_string(),

naga/src/front/wgsl/lower/mod.rs

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ enum LoweredGlobalDecl {
10221022
Const(Handle<ir::Constant>),
10231023
Override(Handle<ir::Override>),
10241024
Type(Handle<ir::Type>),
1025-
EntryPoint,
1025+
EntryPoint(usize),
10261026
}
10271027

10281028
enum Texture {
@@ -1130,6 +1130,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
11301130
layouter: &mut proc::Layouter::default(),
11311131
global_expression_kind_tracker: &mut proc::ExpressionKindTracker::new(),
11321132
};
1133+
if !tu.doc_comments.is_empty() {
1134+
ctx.module.get_or_insert_default_doc_comments().module =
1135+
tu.doc_comments.iter().map(|s| s.to_string()).collect();
1136+
}
11331137

11341138
for decl_handle in self.index.visit_ordered() {
11351139
let span = tu.decls.get_span(decl_handle);
@@ -1138,6 +1142,29 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
11381142
match decl.kind {
11391143
ast::GlobalDeclKind::Fn(ref f) => {
11401144
let lowered_decl = self.function(f, span, &mut ctx)?;
1145+
if !f.doc_comments.is_empty() {
1146+
match lowered_decl {
1147+
LoweredGlobalDecl::Function { handle, .. } => {
1148+
ctx.module
1149+
.get_or_insert_default_doc_comments()
1150+
.functions
1151+
.insert(
1152+
handle,
1153+
f.doc_comments.iter().map(|s| s.to_string()).collect(),
1154+
);
1155+
}
1156+
LoweredGlobalDecl::EntryPoint(index) => {
1157+
ctx.module
1158+
.get_or_insert_default_doc_comments()
1159+
.entry_points
1160+
.insert(
1161+
index,
1162+
f.doc_comments.iter().map(|s| s.to_string()).collect(),
1163+
);
1164+
}
1165+
_ => {}
1166+
}
1167+
}
11411168
ctx.globals.insert(f.name.name, lowered_decl);
11421169
}
11431170
ast::GlobalDeclKind::Var(ref v) => {
@@ -1173,6 +1200,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
11731200
span,
11741201
);
11751202

1203+
if !v.doc_comments.is_empty() {
1204+
ctx.module
1205+
.get_or_insert_default_doc_comments()
1206+
.global_variables
1207+
.insert(
1208+
handle,
1209+
v.doc_comments.iter().map(|s| s.to_string()).collect(),
1210+
);
1211+
}
11761212
ctx.globals
11771213
.insert(v.name.name, LoweredGlobalDecl::Var(handle));
11781214
}
@@ -1203,6 +1239,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
12031239

12041240
ctx.globals
12051241
.insert(c.name.name, LoweredGlobalDecl::Const(handle));
1242+
if !c.doc_comments.is_empty() {
1243+
ctx.module
1244+
.get_or_insert_default_doc_comments()
1245+
.constants
1246+
.insert(
1247+
handle,
1248+
c.doc_comments.iter().map(|s| s.to_string()).collect(),
1249+
);
1250+
}
12061251
}
12071252
ast::GlobalDeclKind::Override(ref o) => {
12081253
let explicit_ty =
@@ -1249,6 +1294,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
12491294
let handle = self.r#struct(s, span, &mut ctx)?;
12501295
ctx.globals
12511296
.insert(s.name.name, LoweredGlobalDecl::Type(handle));
1297+
if !s.doc_comments.is_empty() {
1298+
ctx.module
1299+
.get_or_insert_default_doc_comments()
1300+
.types
1301+
.insert(
1302+
handle,
1303+
s.doc_comments.iter().map(|s| s.to_string()).collect(),
1304+
);
1305+
}
12521306
}
12531307
ast::GlobalDeclKind::Type(ref alias) => {
12541308
let ty = self.resolve_named_ast_type(
@@ -1469,7 +1523,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
14691523
workgroup_size_overrides,
14701524
function,
14711525
});
1472-
Ok(LoweredGlobalDecl::EntryPoint)
1526+
Ok(LoweredGlobalDecl::EntryPoint(
1527+
ctx.module.entry_points.len() - 1,
1528+
))
14731529
} else {
14741530
let handle = ctx.module.functions.append(function, span);
14751531
Ok(LoweredGlobalDecl::Function {
@@ -2086,7 +2142,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
20862142
}
20872143
LoweredGlobalDecl::Function { .. }
20882144
| LoweredGlobalDecl::Type(_)
2089-
| LoweredGlobalDecl::EntryPoint => {
2145+
| LoweredGlobalDecl::EntryPoint(_) => {
20902146
return Err(Box::new(Error::Unexpected(span, ExpectedToken::Variable)));
20912147
}
20922148
};
@@ -2373,7 +2429,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
23732429
function_span,
23742430
ExpectedToken::Function,
23752431
))),
2376-
Some(&LoweredGlobalDecl::EntryPoint) => {
2432+
Some(&LoweredGlobalDecl::EntryPoint(_)) => {
23772433
Err(Box::new(Error::CalledEntryPoint(function_span)))
23782434
}
23792435
Some(&LoweredGlobalDecl::Function {
@@ -3581,6 +3637,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
35813637
let mut struct_alignment = proc::Alignment::ONE;
35823638
let mut members = Vec::with_capacity(s.members.len());
35833639

3640+
let mut doc_comments: Vec<Option<Vec<String>>> = Vec::new();
3641+
35843642
for member in s.members.iter() {
35853643
let ty = self.resolve_ast_type(member.ty, &mut ctx.as_const())?;
35863644

@@ -3623,6 +3681,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
36233681
offset = member_alignment.round_up(offset);
36243682
struct_alignment = struct_alignment.max(member_alignment);
36253683

3684+
if !member.doc_comments.is_empty() {
3685+
doc_comments.push(Some(
3686+
member.doc_comments.iter().map(|s| s.to_string()).collect(),
3687+
));
3688+
}
36263689
members.push(ir::StructMember {
36273690
name: Some(member.name.name.to_owned()),
36283691
ty,
@@ -3646,6 +3709,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
36463709
},
36473710
span,
36483711
);
3712+
for (i, c) in doc_comments.drain(..).enumerate() {
3713+
if let Some(comment) = c {
3714+
ctx.module
3715+
.get_or_insert_default_doc_comments()
3716+
.struct_members
3717+
.insert((handle, i), comment);
3718+
}
3719+
}
36493720
Ok(handle)
36503721
}
36513722

naga/src/front/wgsl/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub use crate::front::wgsl::error::ParseError;
1515
pub use crate::front::wgsl::parse::directive::language_extension::{
1616
ImplementedLanguageExtension, LanguageExtension, UnimplementedLanguageExtension,
1717
};
18+
pub use crate::front::wgsl::parse::Options;
1819

1920
use alloc::boxed::Box;
2021
use thiserror::Error;
@@ -31,12 +32,20 @@ pub(crate) type Result<'a, T> = core::result::Result<T, Box<Error<'a>>>;
3132

3233
pub struct Frontend {
3334
parser: Parser,
35+
options: Options,
3436
}
3537

3638
impl Frontend {
3739
pub const fn new() -> Self {
3840
Self {
3941
parser: Parser::new(),
42+
options: Options::new(),
43+
}
44+
}
45+
pub const fn new_with_options(options: Options) -> Self {
46+
Self {
47+
parser: Parser::new(),
48+
options,
4049
}
4150
}
4251

@@ -45,7 +54,7 @@ impl Frontend {
4554
}
4655

4756
fn inner<'a>(&mut self, source: &'a str) -> Result<'a, crate::Module> {
48-
let tu = self.parser.parse(source)?;
57+
let tu = self.parser.parse(source, &self.options)?;
4958
let index = index::Index::generate(&tu)?;
5059
let module = Lowerer::new(&index).lower(tu)?;
5160

naga/src/front/wgsl/parse/ast.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub struct TranslationUnit<'a> {
4040
/// See [`DiagnosticFilterNode`] for details on how the tree is represented and used in
4141
/// validation.
4242
pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
43+
44+
/// Doc comments appearing first in the file.
45+
/// This serves as documentation for the whole TranslationUnit.
46+
pub doc_comments: Vec<&'a str>,
4347
}
4448

4549
#[derive(Debug, Clone, Copy)]
@@ -137,6 +141,7 @@ pub struct Function<'a> {
137141
pub result: Option<FunctionResult<'a>>,
138142
pub body: Block<'a>,
139143
pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
144+
pub doc_comments: Vec<&'a str>,
140145
}
141146

142147
#[derive(Debug)]
@@ -163,6 +168,7 @@ pub struct GlobalVariable<'a> {
163168
pub binding: Option<ResourceBinding<'a>>,
164169
pub ty: Option<Handle<Type<'a>>>,
165170
pub init: Option<Handle<Expression<'a>>>,
171+
pub doc_comments: Vec<&'a str>,
166172
}
167173

168174
#[derive(Debug)]
@@ -172,12 +178,14 @@ pub struct StructMember<'a> {
172178
pub binding: Option<Binding<'a>>,
173179
pub align: Option<Handle<Expression<'a>>>,
174180
pub size: Option<Handle<Expression<'a>>>,
181+
pub doc_comments: Vec<&'a str>,
175182
}
176183

177184
#[derive(Debug)]
178185
pub struct Struct<'a> {
179186
pub name: Ident<'a>,
180187
pub members: Vec<StructMember<'a>>,
188+
pub doc_comments: Vec<&'a str>,
181189
}
182190

183191
#[derive(Debug)]
@@ -191,6 +199,7 @@ pub struct Const<'a> {
191199
pub name: Ident<'a>,
192200
pub ty: Option<Handle<Type<'a>>>,
193201
pub init: Handle<Expression<'a>>,
202+
pub doc_comments: Vec<&'a str>,
194203
}
195204

196205
#[derive(Debug)]

0 commit comments

Comments
 (0)