wasm-bindgen/crates/webidl/src/first_pass.rs
Stephan Wolski 4cc069bd01 Clean up Some Clippy Warnings (#478)
* clippy: it is more idiomatic to loop over references to containers instead of using explicit iteration methods

* clippy: useless use of `format!`

* clippy: if/else is an expression

* clippy: use of  followed by a function call

* clippy: large size difference between variants

* clippy: redundant closure

* Revert "clippy: large size difference between variants"

This reverts commit 7e2e660dd47c9718126d1c45ae1caa632e287a14.

* Revert "clippy: it is more idiomatic to loop over references to containers instead of using explicit iteration methods"

This reverts commit 5c4804f790fc6a33a7a0f0d2aacdc4b98529b978.
2018-07-15 11:43:55 -05:00

151 lines
4.2 KiB
Rust

use std::{
collections::{BTreeMap, BTreeSet}, mem,
};
use webidl;
use super::Result;
#[derive(Default)]
pub(crate) struct FirstPassRecord<'a> {
pub(crate) interfaces: BTreeSet<String>,
pub(crate) dictionaries: BTreeSet<String>,
pub(crate) enums: BTreeSet<String>,
pub(crate) mixins: BTreeMap<String, MixinData<'a>>,
}
#[derive(Default)]
pub(crate) struct MixinData<'a> {
pub(crate) non_partial: Option<&'a webidl::ast::NonPartialMixin>,
pub(crate) partials: Vec<&'a webidl::ast::PartialMixin>,
}
pub(crate) trait FirstPass {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()>;
}
impl FirstPass for [webidl::ast::Definition] {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
for def in self {
def.first_pass(record)?;
}
Ok(())
}
}
impl FirstPass for webidl::ast::Definition {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
use webidl::ast::Definition::*;
match self {
Dictionary(dictionary) => dictionary.first_pass(record),
Enum(enum_) => enum_.first_pass(record),
Interface(interface) => interface.first_pass(record),
Mixin(mixin) => mixin.first_pass(record),
_ => {
// Other definitions aren't currently used in the first pass
Ok(())
}
}
}
}
impl FirstPass for webidl::ast::Dictionary {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
use webidl::ast::Dictionary::*;
match self {
NonPartial(dictionary) => dictionary.first_pass(record),
_ => {
// Other dictionaries aren't currently used in the first pass
Ok(())
}
}
}
}
impl FirstPass for webidl::ast::NonPartialDictionary {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
if record.dictionaries.insert(self.name.clone()) {
warn!("Encountered multiple declarations of {}", self.name);
}
Ok(())
}
}
impl FirstPass for webidl::ast::Enum {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
if record.enums.insert(self.name.clone()) {
warn!("Encountered multiple declarations of {}", self.name);
}
Ok(())
}
}
impl FirstPass for webidl::ast::Interface {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
use webidl::ast::Interface::*;
match self {
NonPartial(interface) => interface.first_pass(record),
_ => {
// Other interfaces aren't currently used in the first pass
Ok(())
}
}
}
}
impl FirstPass for webidl::ast::NonPartialInterface {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
if record.interfaces.insert(self.name.clone()) {
warn!("Encountered multiple declarations of {}", self.name);
}
Ok(())
}
}
impl FirstPass for webidl::ast::Mixin {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
use webidl::ast::Mixin::*;
match self {
NonPartial(mixin) => mixin.first_pass(record),
Partial(mixin) => mixin.first_pass(record),
}
}
}
impl FirstPass for webidl::ast::NonPartialMixin {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
let entry = record
.mixins
.entry(self.name.clone())
.or_insert_with(Default::default);
if mem::replace(&mut entry.non_partial, Some(self)).is_some() {
warn!(
"Encounterd multiple declarations of {}, using last encountered",
self.name
);
}
Ok(())
}
}
impl FirstPass for webidl::ast::PartialMixin {
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>) -> Result<()> {
let entry = record
.mixins
.entry(self.name.clone())
.or_insert_with(Default::default);
entry.partials.push(self);
Ok(())
}
}