Coverage Report

Created: 2025-01-09 07:53

/src/wasm-tools/crates/wit-smith/src/generate.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::config::Config;
2
use arbitrary::{Arbitrary, Result, Unstructured};
3
use indexmap::IndexMap;
4
use semver::Version;
5
use std::collections::hash_map::{Entry, HashMap};
6
use std::collections::HashSet;
7
use std::fmt::Write;
8
use std::rc::Rc;
9
use std::str;
10
use wit_parser::*;
11
12
pub struct Generator {
13
    config: Config,
14
    packages: PackageList,
15
    next_interface_id: u32,
16
}
17
18
type TypeList = Vec<Type>;
19
type InterfaceList = IndexMap<String, FileInterface>;
20
type PackageList = Vec<(PackageName, InterfaceList)>;
21
22
struct InterfaceGenerator<'a> {
23
    generator: &'a Generator,
24
    file: &'a mut File,
25
    config: &'a Config,
26
    unique_names: HashSet<String>,
27
    types_in_interface: TypeList,
28
}
29
30
#[derive(Clone)]
31
struct Type {
32
    name: String,
33
    size: usize,
34
    is_resource: bool,
35
}
36
37
pub struct Package {
38
    pub name: PackageName,
39
    pub sources: SourceMap,
40
}
41
42
#[derive(Clone)]
43
pub struct PackageName {
44
    pub namespace: String,
45
    pub name: String,
46
    pub version: Option<Version>,
47
}
48
49
impl Generator {
50
3.56k
    pub fn new(config: Config) -> Generator {
51
3.56k
        Generator {
52
3.56k
            config,
53
3.56k
            packages: Default::default(),
54
3.56k
            next_interface_id: 0,
55
3.56k
        }
56
3.56k
    }
57
58
3.56k
    pub fn generate(&mut self, u: &mut Unstructured<'_>) -> Result<Vec<Package>> {
59
3.56k
        let mut packages = Vec::new();
60
3.56k
        let mut names = HashSet::new();
61
7.12k
        while packages.len() < self.config.max_packages && packages.is_empty() {
62
3.56k
            let (pkg, interfaces) = self.gen_package(u, &mut names)?;
63
3.56k
            if interfaces.len() > 0 {
64
1.92k
                self.packages.push((pkg.name.clone(), interfaces));
65
1.92k
            }
66
3.56k
            packages.push(pkg);
67
        }
68
3.56k
        Ok(packages)
69
3.56k
    }
70
71
3.56k
    fn gen_package(
72
3.56k
        &mut self,
73
3.56k
        u: &mut Unstructured<'_>,
74
3.56k
        names: &mut HashSet<String>,
75
3.56k
    ) -> Result<(Package, InterfaceList)> {
76
3.56k
        let namespace = gen_unique_name(u, names)?;
77
3.56k
        let name = gen_unique_name(u, names)?;
78
3.56k
        let version = if u.arbitrary()? {
79
2.78k
            Some(gen_version(u)?)
80
        } else {
81
774
            None
82
        };
83
3.56k
        let mut ret = Package {
84
3.56k
            name: PackageName {
85
3.56k
                namespace,
86
3.56k
                name,
87
3.56k
                version,
88
3.56k
            },
89
3.56k
            sources: SourceMap::new(),
90
3.56k
        };
91
92
28.0k
        #[derive(Arbitrary, Clone)]
<<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
92
9.08k
        #[derive(Arbitrary, Clone)]
<<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
92
18.9k
        #[derive(Arbitrary, Clone)]
<<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
92
9.08k
        #[derive(Arbitrary, Clone)]
Unexecuted instantiation: <<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::Generator>::gen_package::Generate as arbitrary::Arbitrary>::size_hint::{closure#0}
93
        enum Generate {
94
            Interface,
95
            Use,
96
            World,
97
            Done,
98
        }
99
100
3.56k
        let mut items = 0;
101
3.56k
        let mut empty = true;
102
3.56k
        let mut files = vec![File::default()];
103
3.56k
        let mut package_names = HashSet::new();
104
3.56k
        let mut package = File::default();
105
3.56k
        log::debug!("===================== new package ====================");
106
26.5k
        while items < self.config.max_pkg_items {
107
23.6k
            items += 1;
108
23.6k
            let max = if files.len() < self.config.max_files_per_package {
109
17.5k
                files.len() + 1
110
            } else {
111
6.13k
                files.len()
112
            };
113
23.6k
            let i = u.int_in_range(0..=max)?;
114
23.6k
            let file = match files.get_mut(i) {
115
18.0k
                Some(file) => file,
116
                None => {
117
5.62k
                    files.push(File {
118
5.62k
                        items: Vec::new(),
119
5.62k
                        namespace: package
120
5.62k
                            .interfaces
121
5.62k
                            .iter()
122
5.62k
                            .map(|(k, _)| (k.clone(), Definition::Package))
123
5.62k
                            .collect(),
124
5.62k
                        interfaces: package.interfaces.clone(),
125
5.62k
                    });
126
5.62k
                    files.last_mut().unwrap()
127
                }
128
            };
129
130
            // Only generate Use/Done if we've already generated a world or interface. This ensures
131
            // that we never generate empty packages, which aren't representable.
132
23.6k
            let generate = if empty {
133
4.64k
                u.choose(&[Generate::World, Generate::Interface])?.clone()
134
            } else {
135
18.9k
                u.arbitrary()?
136
            };
137
138
23.6k
            match generate {
139
                Generate::World => {
140
6.95k
                    let name = file.gen_unique_package_name(u, &mut package_names)?;
141
6.95k
                    log::debug!("new world `{name}` in {i}");
142
6.95k
                    let world = self.gen_world(u, &name, file)?;
143
6.95k
                    file.items.push(world);
144
6.95k
145
6.95k
                    empty = false;
146
                }
147
                Generate::Interface => {
148
14.7k
                    let name = file.gen_unique_package_name(u, &mut package_names)?;
149
14.7k
                    log::debug!("new interface `{name}` in {i}");
150
14.7k
                    let id = self.next_interface_id;
151
14.7k
                    self.next_interface_id += 1;
152
14.7k
                    let (src, types) = self.gen_interface(u, Some(&name), file)?;
153
14.7k
                    file.items.push(src);
154
14.7k
                    if types.is_empty() {
155
11.4k
                        continue;
156
3.32k
                    }
157
3.32k
                    let interface = FileInterface {
158
3.32k
                        name,
159
3.32k
                        id,
160
3.32k
                        types: Rc::new(types),
161
3.32k
                    };
162
3.32k
163
3.32k
                    // This interface is defined at the package level, and it
164
3.32k
                    // must be unique.
165
3.32k
                    let prev = package
166
3.32k
                        .interfaces
167
3.32k
                        .insert(interface.name.clone(), interface.clone());
168
3.32k
                    assert!(prev.is_none());
169
170
                    // This is also defined at the file level, and it must be
171
                    // unique here too.
172
3.32k
                    let prev = file
173
3.32k
                        .interfaces
174
3.32k
                        .insert(interface.name.clone(), interface.clone());
175
3.32k
                    assert!(prev.is_none());
176
177
                    // Insert the definition into all other files as well.
178
7.82k
                    for file in files.iter_mut() {
179
7.82k
                        file.insert_definition(interface.clone());
180
7.82k
                    }
181
182
3.32k
                    empty = false;
183
                }
184
                Generate::Use => {
185
1.29k
                    let mut piece = String::new();
186
1.29k
                    piece.push_str("use ");
187
1.29k
                    let (name, id, types) = match self.gen_path(u, &mut package, &mut piece)? {
188
945
                        Some(i) => i,
189
351
                        None => continue,
190
                    };
191
945
                    let name = name.to_string();
192
945
                    let types = types.clone();
193
945
                    let name =
194
945
                        if file.namespace.get(&name) == Some(&Definition::File) || u.arbitrary()? {
195
769
                            let name = file.gen_unique_file_name(u)?;
196
769
                            piece.push_str(" as %");
197
769
                            piece.push_str(&name);
198
769
                            name
199
                        } else {
200
176
                            file.namespace.insert(name.clone(), Definition::File);
201
176
                            name
202
                        };
203
945
                    piece.push_str(";");
204
945
                    log::debug!("new use `{name}` in {i}");
205
945
                    file.interfaces
206
945
                        .insert(name.clone(), FileInterface { name, id, types });
207
945
                    file.items.push(piece)
208
                }
209
650
                Generate::Done => break,
210
            };
211
        }
212
213
3.56k
        shuffle(u, &mut files)?;
214
9.18k
        for file in files.iter_mut() {
215
9.18k
            shuffle(u, &mut file.items)?;
216
        }
217
218
3.56k
        let mut has_name = false;
219
3.56k
        let len = files.len();
220
9.18k
        for (i, file) in files.iter_mut().enumerate() {
221
9.18k
            let mut s = String::new();
222
9.18k
            if u.arbitrary()? || (!has_name && i == len - 1) {
223
5.54k
                has_name = true;
224
5.54k
                s.push_str("package ");
225
5.54k
                s.push_str("%");
226
5.54k
                s.push_str(&ret.name.namespace);
227
5.54k
                s.push_str(":");
228
5.54k
                s.push_str("%");
229
5.54k
                s.push_str(&ret.name.name);
230
5.54k
                if let Some(version) = &ret.name.version {
231
4.60k
                    s.push_str(&format!("@{version}"));
232
4.60k
                }
233
5.54k
                s.push_str(";\n\n");
234
3.64k
            }
235
22.6k
            for piece in file.items.iter() {
236
22.6k
                s.push_str(&piece);
237
22.6k
                s.push_str("\n\n");
238
22.6k
            }
239
9.18k
            log::trace!("===============================================");
240
9.18k
            log::trace!("{s}");
241
9.18k
            ret.sources.push(format!("wit{i}.wit").as_ref(), &s);
242
        }
243
3.56k
        Ok((ret, package.interfaces))
244
3.56k
    }
245
246
6.95k
    fn gen_world(
247
6.95k
        &mut self,
248
6.95k
        u: &mut Unstructured<'_>,
249
6.95k
        name: &str,
250
6.95k
        file: &mut File,
251
6.95k
    ) -> Result<String> {
252
6.95k
        InterfaceGenerator::new(self, file).gen_world(u, name)
253
6.95k
    }
254
255
14.7k
    fn gen_interface(
256
14.7k
        &mut self,
257
14.7k
        u: &mut Unstructured<'_>,
258
14.7k
        name: Option<&str>,
259
14.7k
        file: &mut File,
260
14.7k
    ) -> Result<(String, TypeList)> {
261
14.7k
        let mut generator = InterfaceGenerator::new(self, file);
262
14.7k
        let ret = generator.gen_interface(u, name)?;
263
14.7k
        Ok((ret, generator.types_in_interface))
264
14.7k
    }
265
266
24.4k
    fn gen_path<'a>(
267
24.4k
        &'a self,
268
24.4k
        u: &mut Unstructured<'_>,
269
24.4k
        file: &'a mut File,
270
24.4k
        dst: &mut String,
271
24.4k
    ) -> Result<Option<(&'a str, u32, &'a Rc<TypeList>)>> {
272
        enum Choice {
273
            Interfaces,
274
            Packages,
275
        }
276
24.4k
        let mut choices = Vec::new();
277
24.4k
        if !file.interfaces.is_empty() {
278
12.2k
            choices.push(Choice::Interfaces);
279
12.2k
        }
280
24.4k
        if !self.packages.is_empty() {
281
0
            choices.push(Choice::Packages);
282
24.4k
        }
283
24.4k
        if choices.is_empty() {
284
12.2k
            return Ok(None);
285
12.2k
        }
286
12.2k
        Ok(match u.choose(&choices)? {
287
            Choice::Interfaces => {
288
12.2k
                let i = u.int_in_range(0..=file.interfaces.len() - 1)?;
289
12.2k
                let (name, i) = file.interfaces.get_index(i).unwrap();
290
12.2k
                // Once a name is used from a file's local namespace then it
291
12.2k
                // can't be overridden in that namespace so switch it to a file
292
12.2k
                // definition from whatever it previously was.
293
12.2k
                file.namespace.insert(name.clone(), Definition::File);
294
12.2k
                dst.push_str("%");
295
12.2k
                dst.push_str(&i.name);
296
12.2k
                Some((&i.name, i.id, &i.types))
297
            }
298
            Choice::Packages => {
299
0
                let (pkg, ifaces) = u.choose(&self.packages)?;
300
0
                dst.push_str("%");
301
0
                dst.push_str(&pkg.namespace);
302
0
                dst.push_str(":");
303
0
                dst.push_str("%");
304
0
                dst.push_str(&pkg.name);
305
0
                dst.push_str("/");
306
0
                let i = u.int_in_range(0..=ifaces.len() - 1)?;
307
0
                let i = &ifaces[i];
308
0
                dst.push_str("%");
309
0
                dst.push_str(&i.name);
310
0
                if let Some(version) = &pkg.version {
311
0
                    dst.push_str(&format!("@{version}"));
312
0
                }
313
0
                Some((&i.name, i.id, &i.types))
314
            }
315
        })
316
24.4k
    }
317
}
318
319
impl<'a> InterfaceGenerator<'a> {
320
32.9k
    fn new(generator: &'a Generator, file: &'a mut File) -> InterfaceGenerator<'a> {
321
32.9k
        InterfaceGenerator {
322
32.9k
            generator,
323
32.9k
            file,
324
32.9k
            config: &generator.config,
325
32.9k
            types_in_interface: Vec::new(),
326
32.9k
            // Claim the name `memory` to avoid conflicting with the canonical
327
32.9k
            // ABI always using a linear memory named `memory`.
328
32.9k
            unique_names: HashSet::from_iter(["memory".to_string()]),
329
32.9k
        }
330
32.9k
    }
331
332
26.0k
    fn gen_interface(&mut self, u: &mut Unstructured<'_>, name: Option<&str>) -> Result<String> {
333
26.0k
        let mut ret = String::new();
334
26.0k
        ret.push_str("interface ");
335
26.0k
        if let Some(name) = name {
336
14.7k
            ret.push_str("%");
337
14.7k
            ret.push_str(name);
338
14.7k
            ret.push_str(" ");
339
14.7k
        }
340
26.0k
        ret.push_str("{\n");
341
342
90.1k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
342
64
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
342
90.0k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
342
64
        #[derive(Arbitrary)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_interface::Generate as arbitrary::Arbitrary>::size_hint::{closure#0}
343
        enum Generate {
344
            Use,
345
            Type,
346
            Function,
347
        }
348
349
26.0k
        let mut parts = Vec::new();
350
116k
        while parts.len() < self.config.max_interface_items && u.arbitrary()? {
351
90.0k
            match u.arbitrary()? {
352
                Generate::Use => {
353
13.9k
                    let mut part = String::new();
354
13.9k
                    if self.gen_use(u, &mut part)? {
355
7.53k
                        parts.push(part);
356
7.53k
                    }
357
                }
358
                Generate::Type => {
359
59.6k
                    let name = self.gen_unique_name(u)?;
360
59.6k
                    let (ty, mut typedef) = self.gen_typedef(u, &name)?;
361
59.6k
                    let is_resource = ty.is_resource;
362
59.6k
                    self.types_in_interface.push(ty);
363
59.6k
                    if is_resource {
364
3.93k
                        if u.arbitrary()? {
365
3.51k
                            typedef.push_str(" {\n");
366
3.51k
                            self.gen_resource_funcs(u, &mut typedef)?;
367
3.51k
                            typedef.push_str("}");
368
416
                        } else {
369
416
                            typedef.push_str(";");
370
416
                        }
371
55.6k
                    }
372
59.6k
                    parts.push(typedef);
373
                }
374
                Generate::Function => {
375
16.5k
                    parts.push(self.gen_func(u)?);
376
                }
377
            }
378
        }
379
380
26.0k
        shuffle(u, &mut parts)?;
381
109k
        for part in parts {
382
83.6k
            ret.push_str(&part);
383
83.6k
            ret.push_str("\n\n");
384
83.6k
        }
385
386
26.0k
        ret.push_str("}");
387
26.0k
        Ok(ret)
388
26.0k
    }
389
390
6.95k
    fn gen_world(&mut self, u: &mut Unstructured<'_>, name: &str) -> Result<String> {
391
6.95k
        let mut ret = String::new();
392
6.95k
        ret.push_str("world %");
393
6.95k
        ret.push_str(name);
394
6.95k
        ret.push_str(" {\n");
395
396
15.4k
        #[derive(Arbitrary, Copy, Clone)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
396
150
        #[derive(Arbitrary, Copy, Clone)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
396
15.3k
        #[derive(Arbitrary, Copy, Clone)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
396
150
        #[derive(Arbitrary, Copy, Clone)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::Direction as arbitrary::Arbitrary>::size_hint::{closure#0}
397
        enum Direction {
398
            Import,
399
            Export,
400
        }
401
402
27.6k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
402
42
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
402
27.6k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
402
42
        #[derive(Arbitrary)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_world::ItemKind as arbitrary::Arbitrary>::size_hint::{closure#0}
403
        enum ItemKind {
404
            Func(Direction),
405
            Interface(Direction),
406
            AnonInterface(Direction),
407
            Type,
408
            Use,
409
        }
410
411
6.95k
        let mut parts = Vec::new();
412
6.95k
        let mut imported_interfaces = HashSet::new();
413
6.95k
        let mut exported_interfaces = HashSet::new();
414
6.95k
415
6.95k
        // Claim the name `memory` to avoid conflicting with the canonical
416
6.95k
        // ABI always using a linear memory named `memory`.
417
6.95k
        let mut export_names = HashSet::from_iter(["memory".to_string()]);
418
419
34.5k
        while parts.len() < self.config.max_world_items && !u.is_empty() && u.arbitrary()? {
420
27.6k
            let kind = u.arbitrary::<ItemKind>()?;
421
27.6k
            let (direction, named) = match kind {
422
13.4k
                ItemKind::Func(dir) | ItemKind::AnonInterface(dir) => (Some(dir), true),
423
1.92k
                ItemKind::Interface(dir) => (Some(dir), false),
424
5.02k
                ItemKind::Type => (None, true),
425
7.28k
                ItemKind::Use => (None, false),
426
            };
427
428
27.6k
            let mut part = String::new();
429
27.6k
            if let Some(dir) = direction {
430
15.3k
                part.push_str(match dir {
431
3.88k
                    Direction::Import => "import ",
432
11.4k
                    Direction::Export => "export ",
433
                });
434
12.3k
            }
435
436
27.6k
            let name = if named {
437
18.4k
                let names = match direction {
438
7.60k
                    Some(Direction::Import) | None => &mut self.unique_names,
439
10.8k
                    Some(Direction::Export) => &mut export_names,
440
                };
441
18.4k
                let name = gen_unique_name(u, names)?;
442
18.4k
                if direction.is_some() {
443
13.4k
                    part.push_str("%");
444
13.4k
                    part.push_str(&name);
445
13.4k
                    part.push_str(": ");
446
13.4k
                }
447
18.4k
                Some(name)
448
            } else {
449
9.21k
                None
450
            };
451
452
27.6k
            match kind {
453
                ItemKind::Func(_) => {
454
2.14k
                    self.gen_func_sig(u, &mut part, false)?;
455
                }
456
1.92k
                ItemKind::Interface(dir) => {
457
1.92k
                    let id = match self.generator.gen_path(u, self.file, &mut part)? {
458
1.06k
                        Some((_name, id, _types)) => id,
459
                        // If an interface couldn't be chosen or wasn't
460
                        // chosen then skip this import. A unique name was
461
                        // selecteed above but we just sort of leave that
462
                        // floating in the wild to get handled by some other
463
                        // test case.
464
857
                        None => continue,
465
                    };
466
467
                    // If this interface has already been imported or
468
                    // exported this document can't do so again. Throw out
469
                    // this item in that situation.
470
1.06k
                    let unique = match dir {
471
705
                        Direction::Import => imported_interfaces.insert(id),
472
364
                        Direction::Export => exported_interfaces.insert(id),
473
                    };
474
1.06k
                    if !unique {
475
459
                        continue;
476
610
                    }
477
610
                    part.push_str(";");
478
                }
479
                ItemKind::AnonInterface(_) => {
480
11.2k
                    let iface = InterfaceGenerator::new(self.generator, self.file)
481
11.2k
                        .gen_interface(u, None)?;
482
11.2k
                    part.push_str(&iface);
483
                }
484
485
                ItemKind::Type => {
486
5.02k
                    let name = name.unwrap();
487
5.02k
                    let (ty, typedef) = self.gen_typedef(u, &name)?;
488
5.02k
                    assert!(part.is_empty());
489
5.02k
                    part = typedef;
490
5.02k
                    let is_resource = ty.is_resource;
491
5.02k
                    self.types_in_interface.push(ty);
492
5.02k
493
5.02k
                    if is_resource {
494
828
                        if u.arbitrary()? {
495
772
                            part.push_str(" {\n");
496
772
                            self.gen_resource_funcs(u, &mut part)?;
497
772
                            part.push_str("}");
498
56
                        } else {
499
56
                            part.push_str(";");
500
56
                        }
501
4.19k
                    }
502
                }
503
504
                ItemKind::Use => {
505
7.28k
                    if !self.gen_use(u, &mut part)? {
506
4.57k
                        continue;
507
2.71k
                    }
508
                }
509
            }
510
21.7k
            parts.push(part);
511
        }
512
513
6.95k
        shuffle(u, &mut parts)?;
514
515
28.7k
        for part in parts {
516
21.7k
            ret.push_str(&part);
517
21.7k
            ret.push_str("\n");
518
21.7k
        }
519
520
6.95k
        ret.push_str("}");
521
6.95k
522
6.95k
        Ok(ret)
523
6.95k
    }
524
525
4.29k
    fn gen_resource_funcs(&mut self, u: &mut Unstructured<'_>, ret: &mut String) -> Result<()> {
526
4.29k
        let mut parts = Vec::new();
527
528
20.3k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
528
10
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
528
20.3k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
528
10
        #[derive(Arbitrary)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_resource_funcs::Item as arbitrary::Arbitrary>::size_hint::{closure#0}
529
        enum Item {
530
            Constructor,
531
            Static,
532
            Method,
533
        }
534
535
4.29k
        let mut has_constructor = false;
536
4.29k
        let mut names = HashSet::new();
537
24.6k
        while parts.len() < self.config.max_resource_items && !u.is_empty() && u.arbitrary()? {
538
20.3k
            match u.arbitrary()? {
539
808
                Item::Constructor if has_constructor => {}
540
                Item::Constructor => {
541
978
                    has_constructor = true;
542
978
                    let mut part = format!("constructor");
543
978
                    self.gen_params(u, &mut part, false)?;
544
978
                    part.push_str(";");
545
978
                    parts.push(part);
546
                }
547
                Item::Static => {
548
9.50k
                    let mut part = format!("%");
549
9.50k
                    part.push_str(&gen_unique_name(u, &mut names)?);
550
9.50k
                    part.push_str(": static ");
551
9.50k
                    self.gen_func_sig(u, &mut part, false)?;
552
9.50k
                    parts.push(part);
553
                }
554
                Item::Method => {
555
9.09k
                    let mut part = format!("%");
556
9.09k
                    part.push_str(&gen_unique_name(u, &mut names)?);
557
9.09k
                    part.push_str(": ");
558
9.09k
                    self.gen_func_sig(u, &mut part, true)?;
559
9.09k
                    parts.push(part);
560
                }
561
            }
562
        }
563
564
4.29k
        shuffle(u, &mut parts)?;
565
566
23.8k
        for part in parts {
567
19.5k
            ret.push_str(&part);
568
19.5k
            ret.push_str("\n");
569
19.5k
        }
570
4.29k
        Ok(())
571
4.29k
    }
572
573
21.2k
    fn gen_use(&mut self, u: &mut Unstructured<'_>, part: &mut String) -> Result<bool> {
574
21.2k
        let mut path = String::new();
575
21.2k
        let (_name, _id, types) = match self.generator.gen_path(u, self.file, &mut path)? {
576
10.2k
            Some(types) => types,
577
11.0k
            None => return Ok(false),
578
        };
579
10.2k
        part.push_str("use ");
580
10.2k
        part.push_str(&path);
581
10.2k
        part.push_str(".{");
582
10.2k
        let ty = u.choose(types)?;
583
10.2k
        part.push_str("%");
584
10.2k
        part.push_str(&ty.name);
585
10.2k
        let size = ty.size;
586
10.2k
        let is_resource = ty.is_resource;
587
10.2k
        let name = if self.unique_names.contains(&ty.name) || u.arbitrary()? {
588
9.32k
            part.push_str(" as %");
589
9.32k
            let name = self.gen_unique_name(u)?;
590
9.32k
            part.push_str(&name);
591
9.32k
            name
592
        } else {
593
928
            assert!(self.unique_names.insert(ty.name.clone()));
594
928
            ty.name.clone()
595
        };
596
10.2k
        self.types_in_interface.push(Type {
597
10.2k
            name,
598
10.2k
            size,
599
10.2k
            is_resource,
600
10.2k
        });
601
10.2k
        part.push_str("};");
602
10.2k
        Ok(true)
603
21.2k
    }
604
605
64.6k
    fn gen_typedef(&mut self, u: &mut Unstructured<'_>, name: &str) -> Result<(Type, String)> {
606
64.6k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
606
44
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
606
64.6k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
606
44
        #[derive(Arbitrary)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_typedef::Kind as arbitrary::Arbitrary>::size_hint::{closure#0}
607
        pub enum Kind {
608
            Record,
609
            Flags,
610
            Variant,
611
            Enum,
612
            Anonymous,
613
            Resource,
614
        }
615
616
64.6k
        let mut fuel = self.config.max_type_size;
617
64.6k
        let mut ret = String::new();
618
64.6k
        let mut is_resource = false;
619
64.6k
        match u.arbitrary()? {
620
            Kind::Record => {
621
3.10k
                ret.push_str("record %");
622
3.10k
                ret.push_str(name);
623
3.10k
                ret.push_str(" {\n");
624
3.10k
                for _ in 0..u.int_in_range(1..=self.config.max_type_parts)? {
625
11.0k
                    ret.push_str("  %");
626
11.0k
                    ret.push_str(&self.gen_unique_name(u)?);
627
11.0k
                    ret.push_str(": ");
628
11.0k
                    self.gen_type(u, &mut fuel, &mut ret)?;
629
11.0k
                    ret.push_str(",\n");
630
                }
631
3.10k
                ret.push_str("}");
632
            }
633
            Kind::Variant => {
634
2.12k
                ret.push_str("variant %");
635
2.12k
                ret.push_str(name);
636
2.12k
                ret.push_str(" {\n");
637
2.12k
                for _ in 0..u.int_in_range(1..=self.config.max_type_parts)? {
638
6.89k
                    ret.push_str("  %");
639
6.89k
                    ret.push_str(&self.gen_unique_name(u)?);
640
6.89k
                    if u.arbitrary()? {
641
5.97k
                        ret.push_str("(");
642
5.97k
                        self.gen_type(u, &mut fuel, &mut ret)?;
643
5.97k
                        ret.push_str(")");
644
921
                    }
645
6.89k
                    ret.push_str(",\n");
646
                }
647
2.12k
                ret.push_str("}");
648
            }
649
            Kind::Enum => {
650
50.4k
                ret.push_str("enum %");
651
50.4k
                ret.push_str(name);
652
50.4k
                ret.push_str(" {\n");
653
50.4k
                for _ in 0..u.int_in_range(1..=self.config.max_type_parts)? {
654
172k
                    ret.push_str("  %");
655
172k
                    ret.push_str(&self.gen_unique_name(u)?);
656
172k
                    ret.push_str(",\n");
657
                }
658
50.4k
                ret.push_str("}");
659
            }
660
            Kind::Flags => {
661
1.00k
                ret.push_str("flags %");
662
1.00k
                ret.push_str(name);
663
1.00k
                ret.push_str(" {\n");
664
1.00k
                for _ in 0..u.int_in_range(1..=self.config.max_type_parts)? {
665
3.36k
                    ret.push_str("  %");
666
3.36k
                    ret.push_str(&self.gen_unique_name(u)?);
667
3.36k
                    ret.push_str(",\n");
668
                }
669
1.00k
                ret.push_str("}");
670
            }
671
            Kind::Anonymous => {
672
3.21k
                ret.push_str("type %");
673
3.21k
                ret.push_str(name);
674
3.21k
                ret.push_str(" = ");
675
3.21k
                self.gen_type(u, &mut fuel, &mut ret)?;
676
3.21k
                ret.push_str(";");
677
            }
678
4.76k
            Kind::Resource => {
679
4.76k
                is_resource = true;
680
4.76k
                ret.push_str("resource %");
681
4.76k
                ret.push_str(name);
682
4.76k
            }
683
        }
684
685
64.6k
        let ty = Type {
686
64.6k
            size: self.config.max_type_size - fuel,
687
64.6k
            is_resource,
688
64.6k
            name: name.to_string(),
689
64.6k
        };
690
64.6k
        Ok((ty, ret))
691
64.6k
    }
692
693
291k
    fn gen_type(
694
291k
        &mut self,
695
291k
        u: &mut Unstructured<'_>,
696
291k
        fuel: &mut usize,
697
291k
        dst: &mut String,
698
291k
    ) -> Result<()> {
699
238k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary::{closure#0}
Line
Count
Source
699
4.29k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary::{closure#1}
Line
Count
Source
699
234k
        #[derive(Arbitrary)]
<<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary::{closure#2}
Line
Count
Source
699
4.29k
        #[derive(Arbitrary)]
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#0}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#1}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::arbitrary_take_rest::{closure#2}
Unexecuted instantiation: <<wit_smith::generate::InterfaceGenerator>::gen_type::Kind as arbitrary::Arbitrary>::size_hint::{closure#0}
700
        enum Kind {
701
            Bool,
702
            U8,
703
            U16,
704
            U32,
705
            U64,
706
            S8,
707
            S16,
708
            S32,
709
            S64,
710
            F32,
711
            F64,
712
            Char,
713
            String,
714
            Id,
715
            Tuple,
716
            Option,
717
            Result,
718
            List,
719
            Stream,
720
            Future,
721
            ErrorContext,
722
        }
723
724
291k
        *fuel = match fuel.checked_sub(1) {
725
228k
            Some(fuel) => fuel,
726
            None => {
727
62.1k
                dst.push_str("bool");
728
62.1k
                return Ok(());
729
            }
730
        };
731
        loop {
732
234k
            break match u.arbitrary()? {
733
14.9k
                Kind::Bool => dst.push_str("bool"),
734
2.78k
                Kind::U8 => dst.push_str("u8"),
735
849
                Kind::S8 => dst.push_str("s8"),
736
1.34k
                Kind::U16 => dst.push_str("u16"),
737
2.52k
                Kind::S16 => dst.push_str("s16"),
738
2.83k
                Kind::U32 => dst.push_str("u32"),
739
4.46k
                Kind::S32 => dst.push_str("s32"),
740
1.76k
                Kind::U64 => dst.push_str("u64"),
741
4.99k
                Kind::S64 => dst.push_str("s64"),
742
4.82k
                Kind::F32 => dst.push_str("f32"),
743
22.5k
                Kind::F64 => dst.push_str("f64"),
744
33.6k
                Kind::Char => dst.push_str("char"),
745
1.64k
                Kind::String => dst.push_str("string"),
746
                Kind::Id => {
747
5.17k
                    if self.types_in_interface.is_empty() {
748
1.77k
                        continue;
749
3.40k
                    }
750
3.40k
                    let ty = u.choose(&self.types_in_interface)?;
751
3.40k
                    *fuel = match fuel.checked_sub(ty.size) {
752
3.16k
                        Some(fuel) => fuel,
753
245
                        None => continue,
754
                    };
755
3.16k
                    let own_wrapper = if ty.is_resource && u.arbitrary()? {
756
1.24k
                        dst.push_str("own<");
757
1.24k
                        true
758
                    } else {
759
1.91k
                        false
760
                    };
761
3.16k
                    dst.push_str("%");
762
3.16k
                    dst.push_str(&ty.name);
763
3.16k
                    if own_wrapper {
764
1.24k
                        dst.push_str(">");
765
1.91k
                    }
766
                }
767
                Kind::Tuple => {
768
30.1k
                    let fields = u.int_in_range(1..=self.config.max_type_parts)?;
769
30.1k
                    *fuel = match fuel.checked_sub(fields) {
770
27.9k
                        Some(fuel) => fuel,
771
2.12k
                        None => continue,
772
                    };
773
27.9k
                    dst.push_str("tuple<");
774
100k
                    for i in 0..fields {
775
100k
                        if i > 0 {
776
72.4k
                            dst.push_str(", ");
777
72.4k
                        }
778
100k
                        self.gen_type(u, fuel, dst)?;
779
                    }
780
27.9k
                    dst.push_str(">");
781
                }
782
                Kind::Option => {
783
17.2k
                    *fuel = match fuel.checked_sub(1) {
784
17.1k
                        Some(fuel) => fuel,
785
132
                        None => continue,
786
                    };
787
17.1k
                    dst.push_str("option<");
788
17.1k
                    self.gen_type(u, fuel, dst)?;
789
17.1k
                    dst.push_str(">");
790
                }
791
                Kind::List => {
792
4.25k
                    *fuel = match fuel.checked_sub(1) {
793
4.01k
                        Some(fuel) => fuel,
794
244
                        None => continue,
795
                    };
796
4.01k
                    dst.push_str("list<");
797
4.01k
                    self.gen_type(u, fuel, dst)?;
798
4.01k
                    dst.push_str(">");
799
                }
800
                Kind::Result => {
801
7.60k
                    *fuel = match fuel.checked_sub(2) {
802
6.61k
                        Some(fuel) => fuel,
803
990
                        None => continue,
804
                    };
805
6.61k
                    dst.push_str("result");
806
6.61k
                    let ok = u.arbitrary()?;
807
6.61k
                    let err = u.arbitrary()?;
808
6.61k
                    match (ok, err) {
809
                        (true, true) => {
810
4.42k
                            dst.push_str("<");
811
4.42k
                            self.gen_type(u, fuel, dst)?;
812
4.42k
                            dst.push_str(", ");
813
4.42k
                            self.gen_type(u, fuel, dst)?;
814
4.42k
                            dst.push_str(">");
815
                        }
816
                        (true, false) => {
817
614
                            dst.push_str("<");
818
614
                            self.gen_type(u, fuel, dst)?;
819
614
                            dst.push_str(">");
820
                        }
821
                        (false, true) => {
822
1.39k
                            dst.push_str("<_, ");
823
1.39k
                            self.gen_type(u, fuel, dst)?;
824
1.39k
                            dst.push_str(">");
825
                        }
826
176
                        (false, false) => {}
827
                    }
828
                }
829
                Kind::Stream => {
830
6.22k
                    *fuel = match fuel.checked_sub(1) {
831
6.18k
                        Some(fuel) => fuel,
832
47
                        None => continue,
833
                    };
834
6.18k
                    dst.push_str("stream<");
835
6.18k
                    self.gen_type(u, fuel, dst)?;
836
6.18k
                    dst.push_str(">");
837
                }
838
                Kind::Future => {
839
22.4k
                    *fuel = match fuel.checked_sub(1) {
840
22.3k
                        Some(fuel) => fuel,
841
35
                        None => continue,
842
                    };
843
22.3k
                    if u.arbitrary()? {
844
21.3k
                        dst.push_str("future<");
845
21.3k
                        self.gen_type(u, fuel, dst)?;
846
21.3k
                        dst.push_str(">");
847
1.01k
                    } else {
848
1.01k
                        dst.push_str("future");
849
1.01k
                    }
850
                }
851
42.1k
                Kind::ErrorContext => {
852
42.1k
                    dst.push_str("error-context");
853
42.1k
                }
854
            };
855
        }
856
857
228k
        Ok(())
858
291k
    }
859
860
16.5k
    fn gen_func(&mut self, u: &mut Unstructured<'_>) -> Result<String> {
861
16.5k
        let mut ret = "%".to_string();
862
16.5k
        ret.push_str(&self.gen_unique_name(u)?);
863
16.5k
        ret.push_str(": ");
864
16.5k
        self.gen_func_sig(u, &mut ret, false)?;
865
16.5k
        Ok(ret)
866
16.5k
    }
867
868
37.2k
    fn gen_func_sig(
869
37.2k
        &mut self,
870
37.2k
        u: &mut Unstructured<'_>,
871
37.2k
        dst: &mut String,
872
37.2k
        method: bool,
873
37.2k
    ) -> Result<()> {
874
37.2k
        dst.push_str("func");
875
37.2k
        self.gen_params(u, dst, method)?;
876
37.2k
        if u.arbitrary()? {
877
32.8k
            dst.push_str(" -> ");
878
32.8k
            let mut fuel = self.config.max_type_size;
879
32.8k
            self.gen_type(u, &mut fuel, dst)?;
880
4.40k
        }
881
37.2k
        dst.push_str(";");
882
37.2k
        Ok(())
883
37.2k
    }
884
885
38.2k
    fn gen_params(
886
38.2k
        &mut self,
887
38.2k
        u: &mut Unstructured<'_>,
888
38.2k
        dst: &mut String,
889
38.2k
        method: bool,
890
38.2k
    ) -> Result<()> {
891
38.2k
        dst.push_str("(");
892
38.2k
        let mut names = HashSet::new();
893
38.2k
        if method {
894
9.09k
            names.insert("self".to_string());
895
29.1k
        }
896
38.2k
        let mut fuel = self.config.max_type_size;
897
77.8k
        for i in 0..u.int_in_range(0..=self.config.max_type_parts)? {
898
77.8k
            if i > 0 {
899
42.9k
                dst.push_str(", ");
900
42.9k
            }
901
77.8k
            dst.push_str("%");
902
77.8k
            dst.push_str(&gen_unique_name(u, &mut names)?);
903
77.8k
            dst.push_str(": ");
904
77.8k
            self.gen_type(u, &mut fuel, dst)?;
905
        }
906
38.2k
        dst.push_str(")");
907
38.2k
        Ok(())
908
38.2k
    }
909
910
279k
    fn gen_unique_name(&mut self, u: &mut Unstructured<'_>) -> Result<String> {
911
279k
        gen_unique_name(u, &mut self.unique_names)
912
279k
    }
913
}
914
915
401k
fn gen_unique_name(u: &mut Unstructured<'_>, set: &mut HashSet<String>) -> Result<String> {
916
401k
    let mut name = gen_name(u)?;
917
714k
    while !set.insert(name.clone()) {
918
313k
        write!(&mut name, "{}", set.len()).unwrap();
919
313k
    }
920
401k
    Ok(name)
921
401k
}
922
923
423k
fn gen_name(u: &mut Unstructured<'_>) -> Result<String> {
924
423k
    let size = u.arbitrary_len::<u8>()?;
925
423k
    let size = std::cmp::min(size, 20);
926
423k
    let name = match str::from_utf8(u.peek_bytes(size).unwrap()) {
927
49.1k
        Ok(s) => {
928
49.1k
            u.bytes(size).unwrap();
929
49.1k
            s.to_string()
930
        }
931
374k
        Err(e) => {
932
374k
            let i = e.valid_up_to();
933
374k
            let valid = u.bytes(i).unwrap();
934
374k
            str::from_utf8(valid).unwrap().to_string()
935
        }
936
    };
937
423k
    let name = name
938
423k
        .chars()
939
423k
        .map(|x| if x.is_ascii_lowercase() { x } else { 'x' })
940
423k
        .collect::<String>();
941
423k
    Ok(if name.is_empty() {
942
380k
        "name".to_string()
943
    } else {
944
42.9k
        name
945
    })
946
423k
}
947
948
49.9k
fn shuffle<T>(u: &mut Unstructured<'_>, mut slice: &mut [T]) -> Result<()> {
949
206k
    while slice.len() > 0 {
950
156k
        let pos = u.int_in_range(0..=slice.len() - 1)?;
951
156k
        slice.swap(0, pos);
952
156k
        slice = &mut slice[1..];
953
    }
954
49.9k
    Ok(())
955
49.9k
}
wit_smith::generate::shuffle::<wit_smith::generate::File>
Line
Count
Source
948
3.56k
fn shuffle<T>(u: &mut Unstructured<'_>, mut slice: &mut [T]) -> Result<()> {
949
12.7k
    while slice.len() > 0 {
950
9.18k
        let pos = u.int_in_range(0..=slice.len() - 1)?;
951
9.18k
        slice.swap(0, pos);
952
9.18k
        slice = &mut slice[1..];
953
    }
954
3.56k
    Ok(())
955
3.56k
}
wit_smith::generate::shuffle::<alloc::string::String>
Line
Count
Source
948
46.4k
fn shuffle<T>(u: &mut Unstructured<'_>, mut slice: &mut [T]) -> Result<()> {
949
194k
    while slice.len() > 0 {
950
147k
        let pos = u.int_in_range(0..=slice.len() - 1)?;
951
147k
        slice.swap(0, pos);
952
147k
        slice = &mut slice[1..];
953
    }
954
46.4k
    Ok(())
955
46.4k
}
956
957
#[derive(Default)]
958
struct File {
959
    items: Vec<String>,
960
    namespace: HashMap<String, Definition>,
961
    interfaces: IndexMap<String, FileInterface>,
962
}
963
964
#[derive(Clone)]
965
struct FileInterface {
966
    name: String,
967
    id: u32,
968
    types: Rc<TypeList>,
969
}
970
971
#[derive(PartialEq)]
972
enum Definition {
973
    Package,
974
    File,
975
}
976
977
impl File {
978
21.6k
    fn gen_unique_package_name(
979
21.6k
        &mut self,
980
21.6k
        u: &mut Unstructured<'_>,
981
21.6k
        names: &mut HashSet<String>,
982
21.6k
    ) -> Result<String> {
983
21.6k
        let mut name = gen_name(u)?;
984
        loop {
985
            // Find a package-unique name first
986
36.3k
            if !names.insert(name.clone()) {
987
14.6k
                write!(&mut name, "{}", names.len()).unwrap();
988
14.6k
                continue;
989
21.7k
            }
990
21.7k
991
21.7k
            // Then make sure it's file-unique too
992
21.7k
            if self.claim_file_name(&mut name) {
993
21.6k
                break;
994
10
            }
995
        }
996
21.6k
        Ok(name)
997
21.6k
    }
998
999
769
    fn gen_unique_file_name(&mut self, u: &mut Unstructured<'_>) -> Result<String> {
1000
769
        let mut name = gen_name(u)?;
1001
889
        while !self.claim_file_name(&mut name) {
1002
120
            // try again on the next iteration
1003
120
        }
1004
769
        Ok(name)
1005
769
    }
1006
1007
22.5k
    fn claim_file_name(&mut self, name: &mut String) -> bool {
1008
22.5k
        match self.namespace.entry(name.clone()) {
1009
215
            Entry::Occupied(mut e) => match e.get() {
1010
                // If this name is already claimed elsewhere in the package
1011
                // then that's ok as we're going to shadow it, so switch it
1012
                // to a file definition.
1013
85
                Definition::Package => *e.get_mut() = Definition::File,
1014
1015
                // If it's already defined in the file try to add more stuff
1016
                // to the name to make the next try not collide.
1017
                Definition::File => {
1018
130
                    name.push_str("y");
1019
130
                    write!(name, "{}", self.namespace.len()).unwrap();
1020
130
                    return false;
1021
                }
1022
            },
1023
1024
            // Not defined? Claim it.
1025
22.3k
            Entry::Vacant(v) => {
1026
22.3k
                v.insert(Definition::File);
1027
22.3k
            }
1028
        }
1029
22.4k
        true
1030
22.5k
    }
1031
1032
7.82k
    fn insert_definition(&mut self, def: FileInterface) {
1033
7.82k
        match self.namespace.get(&def.name) {
1034
3.32k
            Some(Definition::File) => return,
1035
0
            Some(Definition::Package) => unreachable!(),
1036
4.50k
            None => {}
1037
4.50k
        }
1038
4.50k
        let prev = self.namespace.insert(def.name.clone(), Definition::Package);
1039
4.50k
        assert!(prev.is_none());
1040
4.50k
        let prev = self.interfaces.insert(def.name.clone(), def);
1041
4.50k
        assert!(prev.is_none());
1042
7.82k
    }
1043
}
1044
1045
2.78k
fn gen_version(u: &mut Unstructured<'_>) -> Result<Version> {
1046
2.78k
    Ok(Version {
1047
2.78k
        major: u.int_in_range(0..=10)?,
1048
2.78k
        minor: u.int_in_range(0..=10)?,
1049
2.78k
        patch: u.int_in_range(0..=10)?,
1050
2.78k
        pre: if u.arbitrary()? {
1051
2.09k
            semver::Prerelease::new("alpha.0").unwrap()
1052
        } else {
1053
693
            semver::Prerelease::EMPTY
1054
        },
1055
2.78k
        build: if u.arbitrary()? {
1056
1.94k
            semver::BuildMetadata::new("1.2.0").unwrap()
1057
        } else {
1058
848
            semver::BuildMetadata::EMPTY
1059
        },
1060
    })
1061
2.78k
}