Auto merge of #9261 - bholley:geckolib_nomsg, r=Manishearth

Remove the msg dependency from style

This is part of slimming down the dependencies of geckolib.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9261)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-01-12 09:23:31 +05:30
commit 3680e82cab
20 changed files with 39 additions and 79 deletions

View file

@ -34,7 +34,6 @@ use ipc_channel::router::ROUTER;
use layout_debug; use layout_debug;
use layout_traits::LayoutThreadFactory; use layout_traits::LayoutThreadFactory;
use log; use log;
use msg::ParseErrorReporter;
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId}; use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
use parallel; use parallel;
@ -65,6 +64,7 @@ use style::animation::Animation;
use style::computed_values::{filter, mix_blend_mode}; use style::computed_values::{filter, mix_blend_mode};
use style::context::{SharedStyleContext, StylistWrapper, ReflowGoal}; use style::context::{SharedStyleContext, StylistWrapper, ReflowGoal};
use style::dom::{TDocument, TElement, TNode}; use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::ParseErrorReporter;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::selector_matching::{Stylist, USER_OR_USER_AGENT_STYLESHEETS}; use style::selector_matching::{Stylist, USER_OR_USER_AGENT_STYLESHEETS};

View file

@ -7,7 +7,6 @@
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate cssparser;
extern crate euclid; extern crate euclid;
extern crate hyper; extern crate hyper;
extern crate ipc_channel; extern crate ipc_channel;
@ -20,12 +19,3 @@ extern crate util;
pub mod compositor_msg; pub mod compositor_msg;
pub mod constellation_msg; pub mod constellation_msg;
pub mod webdriver_msg; pub mod webdriver_msg;
use constellation_msg::PipelineId;
use cssparser::{Parser, SourcePosition};
pub trait ParseErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str);
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync>;
fn pipeline(&self) -> PipelineId;
}

View file

@ -11,12 +11,12 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::element::{Element, StylePriority}; use dom::element::{Element, StylePriority};
use dom::node::{Node, NodeDamage, document_from_node, window_from_node}; use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
use dom::window::Window; use dom::window::Window;
use msg::ParseErrorReporter;
use selectors::parser::PseudoElement; use selectors::parser::PseudoElement;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::Ref; use std::cell::Ref;
use string_cache::Atom; use string_cache::Atom;
use style::error_reporting::ParseErrorReporter;
use style::properties::{PropertyDeclaration, Shorthand}; use style::properties::{PropertyDeclaration, Shorthand};
use style::properties::{is_supported_property, parse_one_declaration}; use style::properties::{is_supported_property, parse_one_declaration};
use util::str::{DOMString, str_join}; use util::str::{DOMString, str_join};

View file

@ -65,7 +65,6 @@ use html5ever::serialize::SerializeOpts;
use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
use msg::ParseErrorReporter;
use selectors::matching::{DeclarationBlock, matches}; use selectors::matching::{DeclarationBlock, matches};
use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str}; use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
@ -78,6 +77,7 @@ use std::default::Default;
use std::mem; use std::mem;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, Namespace, QualName}; use string_cache::{Atom, Namespace, QualName};
use style::error_reporting::ParseErrorReporter;
use style::properties::DeclaredValue; use style::properties::DeclaredValue;
use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size}; use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};

View file

@ -43,7 +43,6 @@ use js::rust::Runtime;
use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ResolvedStyleResponse, ScriptReflow}; use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ResolvedStyleResponse, ScriptReflow};
use layout_interface::{LayoutChan, LayoutRPC, Msg, Reflow, ReflowQueryType}; use layout_interface::{LayoutChan, LayoutRPC, Msg, Reflow, ReflowQueryType};
use libc; use libc;
use msg::ParseErrorReporter;
use msg::constellation_msg::{ConstellationChan, DocumentState, LoadData}; use msg::constellation_msg::{ConstellationChan, DocumentState, LoadData};
use msg::constellation_msg::{MozBrowserEvent, PipelineId, SubpageId, WindowSizeData}; use msg::constellation_msg::{MozBrowserEvent, PipelineId, SubpageId, WindowSizeData};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
@ -75,6 +74,7 @@ use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::{Sender, channel};
use string_cache::Atom; use string_cache::Atom;
use style::context::ReflowGoal; use style::context::ReflowGoal;
use style::error_reporting::ParseErrorReporter;
use time; use time;
use timers::{ActiveTimers, IsInterval, ScheduledCallback, TimerCallback, TimerHandle}; use timers::{ActiveTimers, IsInterval, ScheduledCallback, TimerCallback, TimerHandle};
use url::Url; use url::Url;

View file

@ -4,8 +4,8 @@
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition};
use log; use log;
use msg::ParseErrorReporter;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use style::error_reporting::ParseErrorReporter;
#[derive(JSTraceable, HeapSizeOf)] #[derive(JSTraceable, HeapSizeOf)]
pub struct CSSErrorReporter { pub struct CSSErrorReporter {
@ -24,7 +24,4 @@ impl ParseErrorReporter for CSSErrorReporter {
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
box CSSErrorReporter { pipelineid: self.pipelineid, } box CSSErrorReporter { pipelineid: self.pipelineid, }
} }
fn pipeline(&self) -> PipelineId {
self.pipelineid
}
} }

View file

@ -1778,7 +1778,6 @@ dependencies = [
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -9,9 +9,6 @@ build = "build.rs"
name = "style" name = "style"
path = "lib.rs" path = "lib.rs"
[dependencies.msg]
path = "../msg"
[dependencies.plugins] [dependencies.plugins]
path = "../plugins" path = "../plugins"

View file

@ -5,9 +5,9 @@
use animation::Animation; use animation::Animation;
use app_units::Au; use app_units::Au;
use dom::OpaqueNode; use dom::OpaqueNode;
use error_reporting::ParseErrorReporter;
use euclid::Size2D; use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use msg::ParseErrorReporter;
use selector_matching::Stylist; use selector_matching::Stylist;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;

View file

@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::{Parser, SourcePosition};
use log;
pub trait ParseErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str);
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync>;
}
pub struct StdoutErrorReporter;
impl ParseErrorReporter for StdoutErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str) {
if log_enabled!(log::LogLevel::Info) {
let location = input.source_location(position);
info!("{}:{} {}", location.line, location.column, message)
}
}
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
box StdoutErrorReporter
}
}

View file

@ -31,7 +31,6 @@ extern crate lazy_static;
extern crate log; extern crate log;
#[macro_use] #[macro_use]
extern crate matches; extern crate matches;
extern crate msg;
extern crate num; extern crate num;
extern crate rustc_serialize; extern crate rustc_serialize;
#[macro_use(state_pseudo_classes)] extern crate selectors; #[macro_use(state_pseudo_classes)] extern crate selectors;
@ -50,6 +49,7 @@ pub mod context;
mod custom_properties; mod custom_properties;
pub mod data; pub mod data;
pub mod dom; pub mod dom;
pub mod error_reporting;
pub mod font_face; pub mod font_face;
pub mod matching; pub mod matching;
pub mod media_queries; pub mod media_queries;

View file

@ -4,7 +4,7 @@
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition};
use msg::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use selectors::parser::ParserContext as SelectorParserContext; use selectors::parser::ParserContext as SelectorParserContext;
use stylesheets::Origin; use stylesheets::Origin;
use url::Url; use url::Url;

View file

@ -16,12 +16,12 @@ use std::sync::Arc;
use app_units::Au; use app_units::Au;
use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser, Delimiter, use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser, Delimiter,
DeclarationListParser, parse_important, ToCss, TokenSerializationType}; DeclarationListParser, parse_important, ToCss, TokenSerializationType};
use error_reporting::ParseErrorReporter;
use url::Url; use url::Url;
use util::logical_geometry::{LogicalMargin, PhysicalSide, WritingMode}; use util::logical_geometry::{LogicalMargin, PhysicalSide, WritingMode};
use euclid::SideOffsets2D; use euclid::SideOffsets2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use fnv::FnvHasher; use fnv::FnvHasher;
use msg::ParseErrorReporter;
use string_cache::Atom; use string_cache::Atom;
use computed_values; use computed_values;
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
@ -130,7 +130,7 @@ pub mod longhands {
use parser::ParserContext; use parser::ParserContext;
use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
% endif % endif
use msg::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use properties::longhands; use properties::longhands;
use properties::property_bit_field::PropertyBitField; use properties::property_bit_field::PropertyBitField;
use properties::{ComputedValues, PropertyDeclaration}; use properties::{ComputedValues, PropertyDeclaration};

View file

@ -5,12 +5,9 @@
// For lazy_static // For lazy_static
#![allow(unsafe_code)] #![allow(unsafe_code)]
use cssparser::{Parser, SourcePosition};
use dom::TElement; use dom::TElement;
use log; use error_reporting::{ParseErrorReporter, StdoutErrorReporter};
use media_queries::{Device, MediaType}; use media_queries::{Device, MediaType};
use msg::ParseErrorReporter;
use msg::constellation_msg::PipelineId;
use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet}; use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
use selectors::Element; use selectors::Element;
@ -32,25 +29,6 @@ use viewport::{MaybeNew, ViewportRuleCascade};
pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>; pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;
pub struct StdoutErrorReporter;
impl ParseErrorReporter for StdoutErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str) {
if log_enabled!(log::LogLevel::Info) {
let location = input.source_location(position);
info!("{}:{} {}", location.line, location.column, message)
}
}
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
box StdoutErrorReporter
}
fn pipeline(&self) -> PipelineId {
PipelineId::fake_root_pipeline_id()
}
}
lazy_static! { lazy_static! {
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = { pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = {
let mut stylesheets = vec!(); let mut stylesheets = vec!();

View file

@ -5,9 +5,9 @@
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes}; use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
use cssparser::{AtRuleType, RuleListParser}; use cssparser::{AtRuleType, RuleListParser};
use encoding::EncodingRef; use encoding::EncodingRef;
use error_reporting::ParseErrorReporter;
use font_face::{FontFaceRule, parse_font_face_block}; use font_face::{FontFaceRule, parse_font_face_block};
use media_queries::{Device, MediaQueryList, parse_media_query_list}; use media_queries::{Device, MediaQueryList, parse_media_query_list};
use msg::ParseErrorReporter;
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selectors::parser::{Selector, parse_selector_list}; use selectors::parser::{Selector, parse_selector_list};

1
ports/cef/Cargo.lock generated
View file

@ -1728,7 +1728,6 @@ dependencies = [
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -416,7 +416,6 @@ dependencies = [
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -594,24 +593,6 @@ dependencies = [
"libz-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "msg"
version = "0.0.1"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.0 (git+https://github.com/servo/rust-layers)",
"plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]
[[package]] [[package]]
name = "num" name = "num"
version = "0.1.28" version = "0.1.28"
@ -966,7 +947,6 @@ dependencies = [
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",

1
ports/gonk/Cargo.lock generated
View file

@ -1694,7 +1694,6 @@ dependencies = [
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -5,9 +5,8 @@
use app_units::Au; use app_units::Au;
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition};
use euclid::size::Size2D; use euclid::size::Size2D;
use msg::ParseErrorReporter;
use msg::constellation_msg::PipelineId;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use style::error_reporting::ParseErrorReporter;
use style::media_queries::*; use style::media_queries::*;
use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt};
use style::values::specified; use style::values::specified;
@ -20,9 +19,6 @@ impl ParseErrorReporter for CSSErrorReporterTest {
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
Box::new(CSSErrorReporterTest) Box::new(CSSErrorReporterTest)
} }
fn pipeline(&self) -> PipelineId {
return PipelineId::fake_root_pipeline_id();
}
} }
fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) { fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) {

View file

@ -6,7 +6,7 @@ use cssparser::Parser;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::Size2D; use euclid::size::Size2D;
use media_queries::CSSErrorReporterTest; use media_queries::CSSErrorReporterTest;
use msg::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parser::ParserContext; use style::parser::ParserContext;
use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt};