Skip to content

Commit d5fee8d

Browse files
committed
webidl: move first pass logic to new module
I also updated it so that it is modeled in the same extensible way as the WebidlParse trait.
1 parent 5b952f2 commit d5fee8d

File tree

4 files changed

+263
-137
lines changed

4 files changed

+263
-137
lines changed

crates/webidl/src/first_pass.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
use std::{
2+
collections::{BTreeMap, BTreeSet}, mem,
3+
};
4+
5+
use webidl;
6+
7+
use super::Result;
8+
9+
#[derive(Default)]
10+
pub(crate) struct FirstPassRecord<'a> {
11+
pub(crate) interfaces: BTreeSet<String>,
12+
pub(crate) dictionaries: BTreeSet<String>,
13+
pub(crate) enums: BTreeSet<String>,
14+
pub(crate) mixins: BTreeMap<String, MixinData<'a>>,
15+
}
16+
17+
#[derive(Default)]
18+
pub(crate) struct MixinData<'a> {
19+
pub(crate) non_partial: Option<&'a webidl::ast::NonPartialMixin>,
20+
pub(crate) partials: Vec<&'a webidl::ast::PartialMixin>,
21+
}
22+
23+
pub(crate) trait FirstPass {
24+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()>;
25+
}
26+
27+
impl FirstPass for [webidl::ast::Definition] {
28+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
29+
for def in self {
30+
def.first_pass(record)?;
31+
}
32+
33+
Ok(())
34+
}
35+
}
36+
37+
impl FirstPass for webidl::ast::Definition {
38+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
39+
use webidl::ast::Definition::*;
40+
41+
match self {
42+
Dictionary(dictionary) => dictionary.first_pass(record),
43+
Enum(enum_) => enum_.first_pass(record),
44+
Interface(interface) => interface.first_pass(record),
45+
Mixin(mixin) => mixin.first_pass(record),
46+
_ => {
47+
// Other definitions aren't currently used in the first pass
48+
Ok(())
49+
}
50+
}
51+
}
52+
}
53+
54+
impl FirstPass for webidl::ast::Dictionary {
55+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
56+
use webidl::ast::Dictionary::*;
57+
58+
match self {
59+
NonPartial(dictionary) => dictionary.first_pass(record),
60+
_ => {
61+
// Other dictionaries aren't currently used in the first pass
62+
Ok(())
63+
}
64+
}
65+
}
66+
}
67+
68+
impl FirstPass for webidl::ast::NonPartialDictionary {
69+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
70+
if record.dictionaries.insert(self.name.clone()) {
71+
warn!("Encountered multiple declarations of {}", self.name);
72+
}
73+
74+
Ok(())
75+
}
76+
}
77+
78+
impl FirstPass for webidl::ast::Enum {
79+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
80+
if record.enums.insert(self.name.clone()) {
81+
warn!("Encountered multiple declarations of {}", self.name);
82+
}
83+
84+
Ok(())
85+
}
86+
}
87+
88+
impl FirstPass for webidl::ast::Interface {
89+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
90+
use webidl::ast::Interface::*;
91+
92+
match self {
93+
NonPartial(interface) => interface.first_pass(record),
94+
_ => {
95+
// Other interfaces aren't currently used in the first pass
96+
Ok(())
97+
}
98+
}
99+
}
100+
}
101+
102+
impl FirstPass for webidl::ast::NonPartialInterface {
103+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
104+
if record.interfaces.insert(self.name.clone()) {
105+
warn!("Encountered multiple declarations of {}", self.name);
106+
}
107+
108+
Ok(())
109+
}
110+
}
111+
112+
impl FirstPass for webidl::ast::Mixin {
113+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
114+
use webidl::ast::Mixin::*;
115+
116+
match self {
117+
NonPartial(mixin) => mixin.first_pass(record),
118+
Partial(mixin) => mixin.first_pass(record),
119+
}
120+
}
121+
}
122+
123+
impl FirstPass for webidl::ast::NonPartialMixin {
124+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
125+
let entry = record
126+
.mixins
127+
.entry(self.name.clone())
128+
.or_insert(Default::default());
129+
if mem::replace(&mut entry.non_partial, Some(self)).is_some() {
130+
warn!(
131+
"Encounterd multiple declarations of {}, using last encountered",
132+
self.name
133+
);
134+
}
135+
136+
Ok(())
137+
}
138+
}
139+
140+
impl FirstPass for webidl::ast::PartialMixin {
141+
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
142+
let entry = record
143+
.mixins
144+
.entry(self.name.clone())
145+
.or_insert(Default::default());
146+
entry.partials.push(self);
147+
148+
Ok(())
149+
}
150+
}

0 commit comments

Comments
 (0)