diff --git a/Cargo.lock b/Cargo.lock index 38e39eab333..9b1985dfe38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,7 +309,7 @@ dependencies = [ "azure 0.21.2 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", "compositing 0.0.1", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -325,7 +325,7 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.21.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1060,7 +1060,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1130,7 +1130,7 @@ dependencies = [ name = "gfx_tests" version = "0.0.1" dependencies = [ - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", @@ -1737,7 +1737,7 @@ name = "malloc_size_of" version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", "servo_arc 0.0.1", @@ -2594,7 +2594,7 @@ dependencies = [ "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "dom_struct 0.0.1", @@ -2667,7 +2667,7 @@ dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2740,7 +2740,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", @@ -3145,7 +3145,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "fallible 0.0.1", @@ -3207,7 +3207,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3229,7 +3229,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3247,7 +3247,7 @@ name = "stylo_tests" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", @@ -3836,7 +3836,7 @@ dependencies = [ "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd47addfc77b7e574d24e5434f95bb64a863769dfd4f1d451ca4ff5530ba01a" "checksum core-text 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a23bef779fab70e5e6af23e36eed03a48e1c1687dea8929505d405ea48d1f5e" -"checksum cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05012fcdbdeb4c6f59f67db47c1f879929339274a691ee1fb90c26b297783629" +"checksum cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44313341610282488e1156ad1fedebca51c54766c87a041d0287b10499c04ba1" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac" "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821" diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index fbba07aed82..00eb302369a 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -13,7 +13,7 @@ path = "lib.rs" azure = {git = "https://github.com/servo/rust-azure"} canvas_traits = {path = "../canvas_traits"} compositing = {path = "../compositing"} -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" fnv = "1.0" gleam = "0.4" diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml index 79cb182a5af..091c01dc630 100644 --- a/components/canvas_traits/Cargo.toml +++ b/components/canvas_traits/Cargo.toml @@ -10,7 +10,7 @@ name = "canvas_traits" path = "lib.rs" [dependencies] -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" heapsize = "0.4" heapsize_derive = "0.1" diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml index a47ef2d4c4c..b3c2faa0f05 100644 --- a/components/malloc_size_of/Cargo.toml +++ b/components/malloc_size_of/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] app_units = "0.5.5" -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" hashglobe = { path = "../hashglobe" } servo_arc = { path = "../servo_arc" } diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 5cbfa701bb0..be1af3a2ad5 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -33,7 +33,7 @@ byteorder = "1.0" canvas_traits = {path = "../canvas_traits"} caseless = "0.1.0" cookie = "0.6" -cssparser = "0.21.1" +cssparser = "0.22.0" deny_public_fields = {path = "../deny_public_fields"} devtools_traits = {path = "../devtools_traits"} dom_struct = {path = "../dom_struct"} diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml index 322bdc857b5..0928de56156 100644 --- a/components/script_layout_interface/Cargo.toml +++ b/components/script_layout_interface/Cargo.toml @@ -13,7 +13,7 @@ path = "lib.rs" app_units = "0.5" atomic_refcell = "0.1" canvas_traits = {path = "../canvas_traits"} -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" gfx_traits = {path = "../gfx_traits"} heapsize = "0.4" diff --git a/components/selectors/Cargo.toml b/components/selectors/Cargo.toml index 0fa01f994b3..a7df20358fa 100644 --- a/components/selectors/Cargo.toml +++ b/components/selectors/Cargo.toml @@ -25,7 +25,7 @@ unstable = [] [dependencies] bitflags = "0.7" matches = "0.1" -cssparser = "0.21.1" +cssparser = "0.22.0" log = "0.3" fnv = "1.0" malloc_size_of = { path = "../malloc_size_of" } diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 44ff450aa3e..6b87ed96720 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -7,7 +7,8 @@ use attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE, NamespaceConstraint}; use bloom::BLOOM_HASH_MASK; use builder::{SelectorBuilder, SpecificityAndFlags}; use context::QuirksMode; -use cssparser::{ParseError, BasicParseError, CowRcStr, Delimiter}; +use cssparser::{ParseError, ParseErrorKind, BasicParseError, BasicParseErrorKind}; +use cssparser::{SourceLocation, CowRcStr, Delimiter}; use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter}; use precomputed_hash::PrecomputedHash; use servo_arc::ThinArc; @@ -46,8 +47,10 @@ fn to_ascii_lowercase(s: &str) -> Cow { } } +pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>; + #[derive(Clone, Debug, PartialEq)] -pub enum SelectorParseError<'i, T> { +pub enum SelectorParseErrorKind<'i> { PseudoElementInComplexSelector, NoQualifiedNameInAttributeSelector(Token<'i>), EmptySelector, @@ -66,13 +69,6 @@ pub enum SelectorParseError<'i, T> { ExplicitNamespaceUnexpectedToken(Token<'i>), ClassNeedsIdent(Token<'i>), EmptyNegation, - Custom(T), -} - -impl<'a, T> Into>> for SelectorParseError<'a, T> { - fn into(self) -> ParseError<'a, SelectorParseError<'a, T>> { - ParseError::Custom(self) - } } macro_rules! with_all_bounds { @@ -128,7 +124,7 @@ with_bounds! { pub trait Parser<'i> { type Impl: SelectorImpl; - type Error: 'i; + type Error: 'i + From>; /// Whether the name is a pseudo-element that can be specified with /// the single colon syntax in addition to the double-colon syntax. @@ -138,31 +134,32 @@ pub trait Parser<'i> { /// This function can return an "Err" pseudo-element in order to support CSS2.1 /// pseudo-elements. - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result<::NonTSPseudoClass, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + ParseError<'i, Self::Error>> + { + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_non_ts_functional_pseudo_class<'t> - (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>) - -> Result<::NonTSPseudoClass, - ParseError<'i, SelectorParseError<'i, Self::Error>>> + (&self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>) + -> Result<::NonTSPseudoClass, ParseError<'i, Self::Error>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result<::PseudoElement, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + ParseError<'i, Self::Error>> + { + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_functional_pseudo_element<'t> - (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>) - -> Result<::PseudoElement, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + (&self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>) + -> Result<::PseudoElement, ParseError<'i, Self::Error>> + { + Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn default_namespace(&self) -> Option<::NamespaceUrl> { @@ -183,9 +180,9 @@ impl SelectorList { /// https://drafts.csswg.org/selectors/#grouping /// /// Return the Selectors or Err if there is an invalid selector. - pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E> { + pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result> + where P: Parser<'i, Impl=Impl> { let mut values = SmallVec::new(); loop { values.push(input.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?); @@ -1052,24 +1049,28 @@ fn display_to_css_identifier(x: &T, dest: &mut W) -> /// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; /// /// `Err` means invalid selector. -fn parse_selector<'i, 't, P, E, Impl>( +fn parse_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>) - -> Result, ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let mut builder = SelectorBuilder::default(); - let mut parsed_pseudo_element; + let mut has_pseudo_element; 'outer_loop: loop { // Parse a sequence of simple selectors. - parsed_pseudo_element = match parse_compound_selector(parser, input, &mut builder) { - Ok(result) => result, - Err(ParseError::Custom(SelectorParseError::EmptySelector)) if builder.has_combinators() => - return Err(SelectorParseError::DanglingCombinator.into()), - Err(e) => return Err(e), + has_pseudo_element = match parse_compound_selector(parser, input, &mut builder)? { + Some(has_pseudo_element) => has_pseudo_element, + None => { + return Err(input.new_custom_error(if builder.has_combinators() { + SelectorParseErrorKind::DanglingCombinator + } else { + SelectorParseErrorKind::EmptySelector + })) + } }; - if parsed_pseudo_element { + if has_pseudo_element { break; } @@ -1107,18 +1108,18 @@ fn parse_selector<'i, 't, P, E, Impl>( builder.push_combinator(combinator); } - Ok(Selector(builder.build(parsed_pseudo_element))) + Ok(Selector(builder.build(has_pseudo_element))) } impl Selector { /// Parse a selector, without any pseudo-element. - pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E> + pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result> + where P: Parser<'i, Impl=Impl> { let selector = parse_selector(parser, input)?; if selector.has_pseudo_element() { - return Err(ParseError::Custom(SelectorParseError::PseudoElementInComplexSelector)) + return Err(input.new_custom_error(SelectorParseErrorKind::PseudoElementInComplexSelector)) } Ok(selector) } @@ -1127,14 +1128,14 @@ impl Selector { /// * `Err(())`: Invalid selector, abort /// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed. /// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) -fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E>, +fn parse_type_selector<'i, 't, P, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S) + -> Result> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl, S: Push>, { match parse_qualified_name(parser, input, /* in_attr_selector = */ false) { - Err(ParseError::Basic(BasicParseError::EndOfInput)) | + Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) | Ok(OptionalQName::None(_)) => Ok(false), Ok(OptionalQName::Some(namespace, local_name)) => { match namespace { @@ -1214,12 +1215,11 @@ enum OptionalQName<'i, Impl: SelectorImpl> { /// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed, /// but the token is still returned. /// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector -fn parse_qualified_name<'i, 't, P, E, Impl> +fn parse_qualified_name<'i, 't, P, Impl> (parser: &P, input: &mut CssParser<'i, 't>, in_attr_selector: bool) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let default_namespace = |local_name| { let namespace = match parser.default_namespace() { @@ -1230,16 +1230,25 @@ fn parse_qualified_name<'i, 't, P, E, Impl> }; let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| { + let location = input.current_source_location(); match input.next_including_whitespace() { Ok(&Token::Delim('*')) if !in_attr_selector => { Ok(OptionalQName::Some(namespace, None)) - }, + } Ok(&Token::Ident(ref local_name)) => { Ok(OptionalQName::Some(namespace, Some(local_name.clone()))) - }, - Ok(t) if in_attr_selector => Err(SelectorParseError::InvalidQualNameInAttr(t.clone()).into()), - Ok(t) => Err(SelectorParseError::ExplicitNamespaceUnexpectedToken(t.clone()).into()), - Err(e) => Err(ParseError::Basic(e)), + } + Ok(t) if in_attr_selector => { + Err(location.new_custom_error( + SelectorParseErrorKind::InvalidQualNameInAttr(t.clone()) + )) + } + Ok(t) => { + Err(location.new_custom_error( + SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone()) + )) + } + Err(e) => Err(e.into()), } }; @@ -1252,8 +1261,8 @@ fn parse_qualified_name<'i, 't, P, E, Impl> Ok(&Token::Delim('|')) => { let prefix = value.as_ref().into(); let result = parser.namespace_for_prefix(&prefix); - let url = result.ok_or(ParseError::Custom( - SelectorParseError::ExpectedNamespace(value)))?; + let url = result.ok_or(after_ident.source_location().new_custom_error( + SelectorParseErrorKind::ExpectedNamespace(value)))?; explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url)) }, _ => { @@ -1277,8 +1286,10 @@ fn parse_qualified_name<'i, 't, P, E, Impl> input.reset(&after_star); if in_attr_selector { match result { - Ok(t) => Err(SelectorParseError::ExpectedBarInAttr(t).into()), - Err(e) => Err(ParseError::Basic(e)), + Ok(t) => Err(after_star.source_location().new_custom_error( + SelectorParseErrorKind::ExpectedBarInAttr(t) + )), + Err(e) => Err(e.into()), } } else { default_namespace(None) @@ -1301,16 +1312,18 @@ fn parse_qualified_name<'i, 't, P, E, Impl> } -fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_attribute_selector<'i, 't, P, Impl>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let namespace; let local_name; match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? { - OptionalQName::None(t) => - return Err(ParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t))), + OptionalQName::None(t) => { + return Err(input.new_custom_error( + SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t) + )) + } OptionalQName::Some(_, None) => unreachable!(), OptionalQName::Some(ns, Some(ln)) => { local_name = ln; @@ -1333,6 +1346,7 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } } + let location = input.current_source_location(); let operator = match input.next() { // [foo] Err(_) => { @@ -1366,13 +1380,16 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring, // [foo$=bar] Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix, - Ok(t) => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector(t.clone()).into()) + Ok(t) => return Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()) + )) }; let value = match input.expect_ident_or_string() { Ok(t) => t.clone(), - Err(BasicParseError::UnexpectedToken(t)) => - return Err(SelectorParseError::BadValueInAttr(t.clone()).into()), + Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => { + return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t))) + } Err(e) => return Err(e.into()), }; let never_matches = match operator { @@ -1431,9 +1448,10 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } -fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>) - -> Result>> { +fn parse_attribute_flags<'i, 't>(input: &mut CssParser<'i, 't>) + -> Result> +{ + let location = input.current_source_location(); match input.next() { Err(_) => { // Selectors spec says language-defined, but HTML says sensitive. @@ -1442,18 +1460,17 @@ fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>) Ok(&Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => { Ok(ParsedCaseSensitivity::AsciiCaseInsensitive) } - Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))) + Ok(t) => Err(location.new_basic_unexpected_token_error(t.clone())) } } /// Level 3: Parse **one** simple_selector. (Though we might insert a second /// implied "|*" type selector.) -fn parse_negation<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_negation<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { // We use a sequence because a type selector may be represented as two Components. let mut sequence = SmallVec::<[Component; 2]>::new(); @@ -1464,8 +1481,9 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, // that there are no trailing tokens after we're done. let is_type_sel = match parse_type_selector(parser, input, &mut sequence) { Ok(result) => result, - Err(ParseError::Basic(BasicParseError::EndOfInput)) => - return Err(SelectorParseError::EmptyNegation.into()), + Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) => { + return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)) + } Err(e) => return Err(e.into()), }; if !is_type_sel { @@ -1474,10 +1492,10 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, sequence.push(s); }, None => { - return Err(ParseError::Custom(SelectorParseError::EmptyNegation)); + return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)); }, Some(SimpleSelectorParseResult::PseudoElement(_)) => { - return Err(ParseError::Custom(SelectorParseError::NonSimpleSelectorInNegation)); + return Err(input.new_custom_error(SelectorParseErrorKind::NonSimpleSelectorInNegation)); } } } @@ -1491,14 +1509,15 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, /// | [ HASH | class | attrib | pseudo | negation ]+ /// /// `Err(())` means invalid selector. +/// `Ok(None)` is an empty selector /// /// The boolean represent whether a pseudo-element has been parsed. -fn parse_compound_selector<'i, 't, P, E, Impl>( +fn parse_compound_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, builder: &mut SelectorBuilder) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { input.skip_whitespace(); @@ -1528,24 +1547,32 @@ fn parse_compound_selector<'i, 't, P, E, Impl>( let mut state_selectors = SmallVec::<[Component; 3]>::new(); loop { + let location = input.current_source_location(); match input.next_including_whitespace() { Ok(&Token::Colon) => {}, Ok(&Token::WhiteSpace(_)) | Err(_) => break, Ok(t) => - return Err(SelectorParseError::PseudoElementExpectedColon(t.clone()).into()), + return Err(location.new_custom_error( + SelectorParseErrorKind::PseudoElementExpectedColon(t.clone()) + )), } + let location = input.current_source_location(); // TODO(emilio): Functional pseudo-classes too? // We don't need it for now. let name = match input.next_including_whitespace()? { &Token::Ident(ref name) => name.clone(), - t => return Err(SelectorParseError::NoIdentForPseudo(t.clone()).into()), + t => return Err(location.new_custom_error( + SelectorParseErrorKind::NoIdentForPseudo(t.clone()) + )), }; let pseudo_class = - P::parse_non_ts_pseudo_class(parser, name.clone())?; + P::parse_non_ts_pseudo_class(parser, location, name.clone())?; if !p.supports_pseudo_class(&pseudo_class) { - return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()); + return Err(input.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name) + )); } state_selectors.push(Component::NonTSPseudoClass(pseudo_class)); } @@ -1567,28 +1594,29 @@ fn parse_compound_selector<'i, 't, P, E, Impl>( } if empty { // An empty selector is invalid. - Err(ParseError::Custom(SelectorParseError::EmptySelector)) + Ok(None) } else { - Ok(pseudo) + Ok(Some(pseudo)) } } -fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>, - name: CowRcStr<'i>, - inside_negation: bool) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_functional_pseudo_class<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>, + name: CowRcStr<'i>, + inside_negation: bool) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { match_ignore_ascii_case! { &name, - "nth-child" => return parse_nth_pseudo_class(input, Component::NthChild), - "nth-of-type" => return parse_nth_pseudo_class(input, Component::NthOfType), - "nth-last-child" => return parse_nth_pseudo_class(input, Component::NthLastChild), - "nth-last-of-type" => return parse_nth_pseudo_class(input, Component::NthLastOfType), + "nth-child" => return Ok(parse_nth_pseudo_class(input, Component::NthChild)?), + "nth-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthOfType)?), + "nth-last-child" => return Ok(parse_nth_pseudo_class(input, Component::NthLastChild)?), + "nth-last-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthLastOfType)?), "not" => { if inside_negation { - return Err(ParseError::Custom(SelectorParseError::UnexpectedIdent("not".into()))); + return Err(input.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("not".into()) + )); } return parse_negation(parser, input) }, @@ -1599,9 +1627,8 @@ fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P, } -fn parse_nth_pseudo_class<'i, 't, Impl, F, E>(input: &mut CssParser<'i, 't>, selector: F) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> +fn parse_nth_pseudo_class<'i, 't, Impl, F>(input: &mut CssParser<'i, 't>, selector: F) + -> Result, BasicParseError<'i>> where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component { let (a, b) = parse_nth(input)?; Ok(selector(a, b)) @@ -1624,12 +1651,12 @@ pub fn is_css2_pseudo_element<'i>(name: &CowRcStr<'i>) -> bool { /// * `Err(())`: Invalid selector, abort /// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed. /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element -fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>, - inside_negation: bool) - -> Result>, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_one_simple_selector<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>, + inside_negation: bool) + -> Result>, + ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let start = input.state(); // FIXME: remove clone() when lifetimes are non-lexical @@ -1639,12 +1666,15 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) } Ok(Token::Delim('.')) => { + let location = input.current_source_location(); match *input.next_including_whitespace()? { Token::Ident(ref class) => { let class = Component::Class(class.as_ref().into()); Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) } - ref t => Err(SelectorParseError::ClassNeedsIdent(t.clone()).into()), + ref t => Err(location.new_custom_error( + SelectorParseErrorKind::ClassNeedsIdent(t.clone()) + )), } } Ok(Token::SquareBracketBlock) => { @@ -1652,6 +1682,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr))) } Ok(Token::Colon) => { + let location = input.current_source_location(); let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() { Token::Colon => (false, input.next_including_whitespace()?.clone()), t => (true, t), @@ -1659,7 +1690,9 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, let (name, is_functional) = match next_token { Token::Ident(name) => (name, false), Token::Function(name) => (name, true), - t => return Err(SelectorParseError::PseudoElementExpectedIdent(t).into()), + t => return Err(input.new_custom_error( + SelectorParseErrorKind::PseudoElementExpectedIdent(t) + )), }; let is_pseudo_element = !is_single_colon || P::is_pseudo_element_allows_single_colon(&name); @@ -1669,7 +1702,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, P::parse_functional_pseudo_element(parser, name, input) })? } else { - P::parse_pseudo_element(parser, name)? + P::parse_pseudo_element(parser, location, name)? }; Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element))) } else { @@ -1678,7 +1711,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, parse_functional_pseudo_class(parser, input, name, inside_negation) })? } else { - parse_simple_pseudo_class(parser, name)? + parse_simple_pseudo_class(parser, location, name)? }; Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class))) } @@ -1690,10 +1723,10 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, } } -fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_simple_pseudo_class<'i, P, Impl>(parser: &P, location: SourceLocation, + name: CowRcStr<'i>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { (match_ignore_ascii_case! { &name, "first-child" => Ok(Component::FirstChild), @@ -1707,7 +1740,7 @@ fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>) "only-of-type" => Ok(Component::OnlyOfType), _ => Err(()) }).or_else(|()| { - P::parse_non_ts_pseudo_class(parser, name) + P::parse_non_ts_pseudo_class(parser, location, name) .map(Component::NonTSPseudoClass) }) } @@ -1843,36 +1876,37 @@ pub mod tests { impl<'i> Parser<'i> for DummyParser { type Impl = DummySelectorImpl; - type Error = (); + type Error = SelectorParseErrorKind<'i>; - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) - -> Result>> { + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { match_ignore_ascii_case! { &name, - "hover" => Ok(PseudoClass::Hover), - "active" => Ok(PseudoClass::Active), - _ => Err(SelectorParseError::Custom(()).into()) + "hover" => return Ok(PseudoClass::Hover), + "active" => return Ok(PseudoClass::Active), + _ => {} } + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CowRcStr<'i>, parser: &mut CssParser<'i, 't>) - -> Result>> { + -> Result> { match_ignore_ascii_case! { &name, - "lang" => Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())), - _ => Err(SelectorParseError::Custom(()).into()) + "lang" => return Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())), + _ => {} } + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result>> { + SelectorParseError<'i>> { match_ignore_ascii_case! { &name, - "before" => Ok(PseudoElement::Before), - "after" => Ok(PseudoElement::After), - _ => Err(SelectorParseError::Custom(()).into()) + "before" => return Ok(PseudoElement::Before), + "after" => return Ok(PseudoElement::After), + _ => {} } + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn default_namespace(&self) -> Option { @@ -1885,17 +1919,17 @@ pub mod tests { } fn parse<'i>(input: &'i str) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns(input, &DummyParser::default()) } fn parse_expected<'i, 'a>(input: &'i str, expected: Option<&'a str>) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns_expected(input, &DummyParser::default(), expected) } fn parse_ns<'i>(input: &'i str, parser: &DummyParser) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns_expected(input, parser, None) } @@ -1903,7 +1937,7 @@ pub mod tests { input: &'i str, parser: &DummyParser, expected: Option<&'a str> - ) -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + ) -> Result, SelectorParseError<'i>> { let mut parser_input = ParserInput::new(input); let result = SelectorList::parse(parser, &mut CssParser::new(&mut parser_input)); if let Ok(ref selectors) = result { diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 786373c399f..23130d09128 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -36,7 +36,7 @@ atomic_refcell = "0.1" bitflags = "0.7" byteorder = "1.0" cfg-if = "0.1.0" -cssparser = "0.21.2" +cssparser = "0.22.0" encoding = {version = "0.2", optional = true} euclid = "0.15" fallible = { path = "../fallible" } diff --git a/components/style/counter_style/mod.rs b/components/style/counter_style/mod.rs index cb0a9f3d8c7..60e865f7ea8 100644 --- a/components/style/counter_style/mod.rs +++ b/components/style/counter_style/mod.rs @@ -8,18 +8,18 @@ use Atom; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; -use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr}; +use cssparser::{Parser, Token, serialize_identifier, CowRcStr}; use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc; use parser::{ParserContext, ParserErrorContext, Parse}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::ascii::AsciiExt; use std::borrow::Cow; use std::fmt; use std::ops::Range; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use values::CustomIdent; /// Parse the prelude of an @counter-style rule @@ -36,12 +36,13 @@ pub fn parse_counter_style_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result(name: CustomIdent, }; let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { - let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error) + if let Err((error, slice)) = declaration { + let location = error.location; + let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(slice, error); + context.log_css_error(error_context, location, error) } } } @@ -101,7 +103,7 @@ pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent, }; if let Some(error) = error { context.log_css_error(error_context, start, error); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(rule) } @@ -117,7 +119,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for CounterStyleRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } macro_rules! accessor { @@ -186,7 +188,7 @@ macro_rules! counter_style_descriptors { impl<'a, 'b, 'i> DeclarationParser<'i> for CounterStyleRuleParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -201,7 +203,7 @@ macro_rules! counter_style_descriptors { self.rule.$ident = Some(value) } )* - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } Ok(()) } @@ -299,7 +301,7 @@ pub enum System { impl Parse for System { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident_cloned()?, + try_match_ident_ignore_ascii_case! { input, "cyclic" => Ok(System::Cyclic), "numeric" => Ok(System::Numeric), "alphabetic" => Ok(System::Alphabetic), @@ -356,10 +358,11 @@ pub enum Symbol { impl Parse for Symbol { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match input.next() { Ok(&Token::QuotedString(ref s)) => Ok(Symbol::String(s.as_ref().to_owned())), Ok(&Token::Ident(ref s)) => Ok(Symbol::Ident(s.as_ref().to_owned())), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } @@ -414,7 +417,7 @@ impl Parse for Ranges { let opt_end = parse_bound(input)?; if let (Some(start), Some(end)) = (opt_start, opt_end) { if start > end { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } Ok(opt_start..opt_end) @@ -424,10 +427,11 @@ impl Parse for Ranges { } fn parse_bound<'i, 't>(input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(v), .. }) => Ok(Some(v)), Ok(&Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("infinite") => Ok(None), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } @@ -472,7 +476,7 @@ impl Parse for Pad { let pad_with = input.try(|input| Symbol::parse(context, input)); let min_length = input.expect_integer()?; if min_length < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?; Ok(Pad(min_length as u32, pad_with)) @@ -502,7 +506,7 @@ impl Parse for Symbols { symbols.push(s) } else { if symbols.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { return Ok(Symbols(symbols)) } @@ -533,7 +537,7 @@ impl Parse for AdditiveSymbols { let tuples = Vec::::parse(context, input)?; // FIXME maybe? https://github.com/w3c/csswg-drafts/issues/1220 if tuples.windows(2).any(|window| window[0].weight <= window[1].weight) { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(AdditiveSymbols(tuples)) } @@ -557,7 +561,7 @@ impl Parse for AdditiveTuple { let symbol = input.try(|input| Symbol::parse(context, input)); let weight = input.expect_integer()?; if weight < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let symbol = symbol.or_else(|_| Symbol::parse(context, input))?; Ok(AdditiveTuple { @@ -604,7 +608,7 @@ impl Parse for SpeakAs { if is_spell_out { // spell-out is not supported, but don’t parse it as a . // See bug 1024178. - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } result.or_else(|_| { Ok(SpeakAs::Other(parse_counter_style_name(input)?)) diff --git a/components/style/custom_properties.rs b/components/style/custom_properties.rs index ca9e4194970..86dd6063114 100644 --- a/components/style/custom_properties.rs +++ b/components/style/custom_properties.rs @@ -11,14 +11,14 @@ use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSeri use precomputed_hash::PrecomputedHash; use properties::{CSSWideKeyword, DeclaredValue}; use selector_map::{PrecomputedHashSet, PrecomputedHashMap, PrecomputedDiagnosticHashMap}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use smallvec::SmallVec; use std::ascii::AsciiExt; use std::borrow::{Borrow, Cow}; use std::fmt; use std::hash::Hash; -use style_traits::{ToCss, StyleParseError, ParseError}; +use style_traits::{ToCss, StyleParseErrorKind, ParseError}; /// A custom property name is just an `Atom`. /// @@ -357,16 +357,27 @@ fn parse_declaration_value_block<'i, 't>( } token.serialization_type() } - Token::BadUrl(u) => - return Err(StyleParseError::BadUrlInDeclarationValueBlock(u).into()), - Token::BadString(s) => - return Err(StyleParseError::BadStringInDeclarationValueBlock(s).into()), - Token::CloseParenthesis => - return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()), - Token::CloseSquareBracket => - return Err(StyleParseError::UnbalancedCloseSquareBracketInDeclarationValueBlock.into()), - Token::CloseCurlyBracket => - return Err(StyleParseError::UnbalancedCloseCurlyBracketInDeclarationValueBlock.into()), + Token::BadUrl(u) => { + return Err(input.new_custom_error(StyleParseErrorKind::BadUrlInDeclarationValueBlock(u))) + } + Token::BadString(s) => { + return Err(input.new_custom_error(StyleParseErrorKind::BadStringInDeclarationValueBlock(s))) + } + Token::CloseParenthesis => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseParenthesisInDeclarationValueBlock + )) + } + Token::CloseSquareBracket => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseSquareBracketInDeclarationValueBlock + )) + } + Token::CloseCurlyBracket => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseCurlyBracketInDeclarationValueBlock + )) + } Token::Function(ref name) => { if name.eq_ignore_ascii_case("var") { let args_start = input.state(); @@ -446,7 +457,7 @@ fn parse_var_function<'i, 't>( let name = input.expect_ident_cloned()?; let name: Result<_, ParseError> = parse_name(&name) - .map_err(|()| SelectorParseError::UnexpectedIdent(name.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))); let name = name?; if input.try(|input| input.expect_comma()).is_ok() { // Exclude `!` and `;` at the top level diff --git a/components/style/error_reporting.rs b/components/style/error_reporting.rs index 718306323a3..19e89e2338f 100644 --- a/components/style/error_reporting.rs +++ b/components/style/error_reporting.rs @@ -6,8 +6,7 @@ #![deny(missing_docs)] -use cssparser::{BasicParseError, Token, SourceLocation}; -use cssparser::ParseError as CssParseError; +use cssparser::{Token, SourceLocation, ParseErrorKind, BasicParseErrorKind}; use log; use std::fmt; use style_traits::ParseError; @@ -91,24 +90,24 @@ impl<'a> fmt::Display for ContextualParseError<'a> { } fn parse_error_to_str(err: &ParseError, f: &mut fmt::Formatter) -> fmt::Result { - match *err { - CssParseError::Basic(BasicParseError::UnexpectedToken(ref t)) => { + match err.kind { + ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(ref t)) => { write!(f, "found unexpected ")?; token_to_str(t, f) } - CssParseError::Basic(BasicParseError::EndOfInput) => { + ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput) => { write!(f, "unexpected end of input") } - CssParseError::Basic(BasicParseError::AtRuleInvalid(ref i)) => { + ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(ref i)) => { write!(f, "@ rule invalid: {}", i) } - CssParseError::Basic(BasicParseError::AtRuleBodyInvalid) => { + ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid) => { write!(f, "@ rule invalid") } - CssParseError::Basic(BasicParseError::QualifiedRuleInvalid) => { + ParseErrorKind::Basic(BasicParseErrorKind::QualifiedRuleInvalid) => { write!(f, "qualified rule invalid") } - CssParseError::Custom(ref err) => { + ParseErrorKind::Custom(ref err) => { write!(f, "{:?}", err) } } diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 30eb242a6d4..fec122d344c 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -19,10 +19,10 @@ use error_reporting::{ContextualParseError, ParseErrorReporter}; use parser::{ParserContext, ParserErrorContext, Parse}; #[cfg(feature = "gecko")] use properties::longhands::font_language_override; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use values::specified::url::SpecifiedUrl; /// A source for a font-face rule. @@ -100,7 +100,7 @@ impl Parse for FontWeight { result.or_else(|_| { font_weight::T::from_int(input.expect_integer()?) .map(FontWeight::Weight) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }) } } @@ -123,9 +123,10 @@ pub fn parse_font_face_block(context: &ParserContext, }; let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { - let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error); - context.log_css_error(error_context, err.location, error) + if let Err((error, slice)) = declaration { + let location = error.location; + let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error); + context.log_css_error(error_context, location, error) } } } @@ -186,7 +187,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for FontFaceRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl Parse for Source { @@ -287,7 +288,7 @@ macro_rules! font_face_descriptors_common { impl<'a, 'b, 'i> DeclarationParser<'i> for FontFaceRuleParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -302,7 +303,7 @@ macro_rules! font_face_descriptors_common { self.rule.$ident = Some(value) } )* - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } Ok(()) } diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index e0be4e7423f..be42ecd120c 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -7,7 +7,7 @@ use app_units::AU_PER_PX; use app_units::Au; use context::QuirksMode; -use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError}; +use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseErrorKind}; use euclid::ScaleFactor; use euclid::Size2D; use font_metrics::get_metrics_provider_for_product; @@ -30,7 +30,7 @@ use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering}; use str::starts_with_ignore_ascii_case; use string_cache::Atom; use style_traits::{CSSPixel, DevicePixel}; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::ViewportConstraints; use stylesheets::Origin; use values::{CSSFloat, CustomIdent, serialize_dimension}; @@ -285,15 +285,16 @@ impl Resolution { } fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let (value, unit) = match *input.next()? { Token::Dimension { value, ref unit, .. } => { (value, unit) }, - ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => return Err(location.new_unexpected_token_error(t.clone())), }; if value <= 0. { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (match_ignore_ascii_case! { &unit, @@ -301,7 +302,7 @@ impl Resolution { "dppx" => Ok(Resolution::Dppx(value)), "dpcm" => Ok(Resolution::Dpcm(value)), _ => Err(()) - }).map_err(|()| StyleParseError::UnexpectedDimension(unit.clone()).into()) + }).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedDimension(unit.clone()))) } } @@ -498,7 +499,7 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, // for parity with gecko. We should remove this check when we want // to support it. if let Length::Calc(_) = length { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::Length(length) }, @@ -508,14 +509,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, // supported in media queries per FIXME above. let i = input.expect_integer()?; if i < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::Integer(i as u32) } nsMediaFeature_ValueType::eBoolInteger => { let i = input.expect_integer()?; if i < 0 || i > 1 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::BoolInteger(i == 1) } @@ -525,14 +526,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, nsMediaFeature_ValueType::eIntRatio => { let a = input.expect_integer()?; if a <= 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } input.expect_delim('/')?; let b = input.expect_integer()?; if b <= 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::IntRatio(a as u32, b as u32) } @@ -540,28 +541,26 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, MediaExpressionValue::Resolution(Resolution::parse(input)?) } nsMediaFeature_ValueType::eEnumerated => { - let keyword = input.expect_ident()?; - let keyword = unsafe { - bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(), - keyword.len() as u32) - }; + let location = input.current_source_location(); + let keyword = input.expect_ident()?; + let keyword = unsafe { + bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(), + keyword.len() as u32) + }; - let first_table_entry: *const nsCSSProps_KTableEntry = unsafe { - *feature.mData.mKeywordTable.as_ref() - }; + let first_table_entry: *const nsCSSProps_KTableEntry = unsafe { + *feature.mData.mKeywordTable.as_ref() + }; - let value = - match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } { - Some((_kw, value)) => { - value - } - None => return Err(StyleParseError::UnspecifiedError.into()), - }; + let value = match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } { + Some((_kw, value)) => value, + None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)), + }; - MediaExpressionValue::Enumerated(value) + MediaExpressionValue::Enumerated(value) } nsMediaFeature_ValueType::eIdent => { - MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned()) + MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned()) } }; @@ -590,10 +589,10 @@ impl Expression { input: &mut Parser<'i, 't>, ) -> Result> { input.expect_parenthesis_block().map_err(|err| - match err { - BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t), - _ => StyleParseError::UnspecifiedError, - } + err.location.new_custom_error(match err.kind { + BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t), + _ => StyleParseErrorKind::UnspecifiedError, + }) )?; input.parse_nested_block(|input| { @@ -601,11 +600,12 @@ impl Expression { let feature; let range; { + let location = input.current_source_location(); let ident = input.expect_ident().map_err(|err| - match err { - BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t), - _ => StyleParseError::UnspecifiedError, - } + err.location.new_custom_error(match err.kind { + BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t), + _ => StyleParseErrorKind::UnspecifiedError, + }) )?; let mut flags = 0; @@ -648,19 +648,25 @@ impl Expression { Ok((f, r)) => { feature = f; range = r; - }, + } Err(()) => { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()) - }, + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) + } } if (feature.mReqFlags & !flags) != 0 { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()); + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) } if range != nsMediaExpression_Range::eEqual && feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()); + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) } } @@ -671,15 +677,15 @@ impl Expression { // reject them here too. if input.try(|i| i.expect_colon()).is_err() { if range != nsMediaExpression_Range::eEqual { - return Err(StyleParseError::RangedExpressionWithNoValue.into()) + return Err(input.new_custom_error(StyleParseErrorKind::RangedExpressionWithNoValue)) } return Ok(Expression::new(feature, None, range)); } let value = parse_feature_value(feature, feature.mValueType, - context, input).map_err(|_| - StyleParseError::MediaQueryExpectedFeatureValue + context, input).map_err(|err| + err.location.new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue) )?; Ok(Expression::new(feature, Some(value), range)) diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index 56a49f4743a..e9464b657b1 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -4,18 +4,18 @@ //! Gecko-specific bits for selector-parsing. -use cssparser::{BasicParseError, Parser, ToCss, Token, CowRcStr}; +use cssparser::{BasicParseError, BasicParseErrorKind, Parser, ToCss, Token, CowRcStr, SourceLocation}; use element_state::ElementState; use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use selector_parser::{SelectorParser, PseudoElementCascadeType}; use selectors::SelectorList; -use selectors::parser::{Selector, SelectorMethods, SelectorParseError}; +use selectors::parser::{Selector, SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::fmt; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; -use style_traits::{ParseError, StyleParseError}; +use style_traits::{ParseError, StyleParseErrorKind}; pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT}; pub use gecko::snapshot::SnapshotMap; @@ -298,14 +298,14 @@ impl<'a> SelectorParser<'a> { impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { type Impl = SelectorImpl; - type Error = StyleParseError<'i>; + type Error = StyleParseErrorKind<'i>; fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'i>) -> bool { ::selectors::parser::is_css2_pseudo_element(name) || name.starts_with("-moz-tree-") // tree pseudo-elements } - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result> { macro_rules! pseudo_class_parse { (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], @@ -313,8 +313,9 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => { match_ignore_ascii_case! { &name, $($css => NonTSPseudoClass::$name,)* - _ => return Err(::selectors::parser::SelectorParseError::UnsupportedPseudoClassOrElement( - name.clone()).into()) + _ => return Err(location.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()) + )) } } } @@ -322,7 +323,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { if self.is_pseudo_class_enabled(&pseudo_class) { Ok(pseudo_class) } else { - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()) + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } } @@ -355,11 +356,15 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { })?; // Selectors inside `:-moz-any` may not include combinators. if selectors.iter().flat_map(|x| x.iter_raw_match_order()).any(|s| s.is_combinator()) { - return Err(SelectorParseError::UnexpectedIdent("-moz-any".into()).into()) + return Err(parser.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("-moz-any".into()) + )) } NonTSPseudoClass::MozAny(selectors.into_boxed_slice()) } - _ => return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + _ => return Err(parser.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()) + )) } } } @@ -367,13 +372,14 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { if self.is_pseudo_class_enabled(&pseudo_class) { Ok(pseudo_class) } else { - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()) + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result> { + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) - .ok_or(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + .ok_or(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) } fn parse_functional_pseudo_element<'t>(&self, name: CowRcStr<'i>, @@ -384,11 +390,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { // separated by either comma or space. let mut args = Vec::new(); loop { + let location = parser.current_source_location(); match parser.next() { Ok(&Token::Ident(ref ident)) => args.push(ident.as_ref().to_owned()), Ok(&Token::Comma) => {}, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), - Err(BasicParseError::EndOfInput) => break, + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), + Err(BasicParseError { kind: BasicParseErrorKind::EndOfInput, .. }) => break, _ => unreachable!("Parser::next() shouldn't return any other error"), } } @@ -397,7 +404,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { return Ok(pseudo); } } - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) } fn default_namespace(&self) -> Option { diff --git a/components/style/macros.rs b/components/style/macros.rs index 7a5d8ba9abf..a93f7f545e4 100644 --- a/components/style/macros.rs +++ b/components/style/macros.rs @@ -26,14 +26,17 @@ macro_rules! trivial_to_computed_value { /// FIXME(emilio): The fact that `UnexpectedIdent` is a `SelectorParseError` /// doesn't make a lot of sense to me. macro_rules! try_match_ident_ignore_ascii_case { - ($ident:expr, $( $match_body:tt )*) => { - let __ident = $ident; - (match_ignore_ascii_case! { &*__ident, + ($input:expr, $( $match_body:tt )*) => { + let location = $input.current_source_location(); + let ident = $input.expect_ident_cloned()?; + (match_ignore_ascii_case! { &ident, $( $match_body )* _ => Err(()), }) .map_err(|()| { - ::selectors::parser::SelectorParseError::UnexpectedIdent(__ident.clone()).into() + location.new_custom_error( + ::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + ) }) } } @@ -56,7 +59,7 @@ macro_rules! define_numbered_css_keyword_enum { _context: &$crate::parser::ParserContext, input: &mut ::cssparser::Parser<'i, 't>, ) -> Result<$name, ::style_traits::ParseError<'i>> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, $( $css => Ok($name::$variant), )+ } } diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs index 83b3f580922..72401166746 100644 --- a/components/style/media_queries.rs +++ b/components/style/media_queries.rs @@ -12,11 +12,11 @@ use cssparser::{Delimiter, Parser}; use cssparser::{Token, ParserInput}; use error_reporting::{ContextualParseError, ParseErrorReporter}; use parser::{ParserContext, ParserErrorContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use serialize_comma_separated_list; use std::fmt; use str::string_as_ascii_lowercase; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::CustomIdent; #[cfg(feature = "servo")] @@ -210,13 +210,13 @@ impl MediaQuery { let media_type = match input.try(|i| i.expect_ident_cloned()) { Ok(ident) => { let result: Result<_, ParseError> = MediaQueryType::parse(&*ident) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); result? } Err(_) => { // Media type is only optional if qualifier is not specified. if qualifier.is_some() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // Without a media type, require at least one expression. @@ -257,17 +257,17 @@ where let mut media_queries = vec![]; loop { let start_position = input.position(); - let start_location = input.current_source_location(); match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i)) { Ok(mq) => { media_queries.push(mq); }, Err(err) => { media_queries.push(MediaQuery::never_matching()); + let location = err.location; let error = ContextualParseError::InvalidMediaRule( input.slice_from(start_position), err); let error_context = ParserErrorContext { error_reporter }; - context.log_css_error(&error_context, start_location, error); + context.log_css_error(&error_context, location, error); }, } diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index df4840f0dda..64b33ea86e8 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -8,19 +8,18 @@ use context::QuirksMode; use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr}; -use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError}; +use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind}; use custom_properties::CustomPropertiesBuilder; use error_reporting::{ParseErrorReporter, ContextualParseError}; use parser::{ParserContext, ParserErrorContext}; use properties::animated_properties::AnimationValue; -use selectors::parser::SelectorParseError; use shared_lock::Locked; use smallbitvec::{self, SmallBitVec}; use smallvec::SmallVec; use std::fmt; use std::iter::{DoubleEndedIterator, Zip}; use std::slice::Iter; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseError}; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseErrorKind}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; use super::*; use values::computed::Context; @@ -1035,16 +1034,16 @@ pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaratio let mut input = ParserInput::new(input); let mut parser = Parser::new(&mut input); let start_position = parser.position(); - let start_location = parser.current_source_location(); parser.parse_entirely(|parser| { let name = id.name().into(); PropertyDeclaration::parse_into(declarations, id, name, &context, parser) .map_err(|e| e.into()) }).map_err(|err| { + let location = err.location; let error = ContextualParseError::UnsupportedPropertyDeclaration( parser.slice_from(start_position), err); let error_context = ParserErrorContext { error_reporter: error_reporter }; - context.log_css_error(&error_context, start_location, error); + context.log_css_error(&error_context, location, error); }) } @@ -1060,7 +1059,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Importance; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } /// Based on NonMozillaVendorIdentifier from Gecko's CSS parser. @@ -1071,7 +1070,7 @@ fn is_non_mozilla_vendor_identifier(name: &str) -> bool { impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { type Declaration = Importance; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result> { @@ -1079,11 +1078,11 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { let id = match PropertyId::parse(&name, Some(&prop_context)) { Ok(id) => id, Err(()) => { - return Err(if is_non_mozilla_vendor_identifier(&name) { - PropertyDeclarationParseError::UnknownVendorProperty + return Err(input.new_custom_error(if is_non_mozilla_vendor_identifier(&name) { + StyleParseErrorKind::UnknownVendorProperty } else { - PropertyDeclarationParseError::UnknownProperty(name) - }.into()); + StyleParseErrorKind::UnknownProperty(name) + })); } }; input.parse_until_before(Delimiter::Bang, |input| { @@ -1121,19 +1120,18 @@ pub fn parse_property_declaration_list(context: &ParserContext, Ok(importance) => { block.extend(iter.parser.declarations.drain(), importance); } - Err(err) => { + Err((error, slice)) => { iter.parser.declarations.clear(); // If the unrecognized property looks like a vendor-specific property, // silently ignore it instead of polluting the error output. - if let CssParseError::Custom(SelectorParseError::Custom( - StyleParseError::PropertyDeclaration( - PropertyDeclarationParseError::UnknownVendorProperty))) = err.error { + if let ParseErrorKind::Custom(StyleParseErrorKind::UnknownVendorProperty) = error.kind { continue; } - let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + let location = error.location; + let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error); + context.log_css_error(error_context, location, error); } } } diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 41995060941..d8f6b10f444 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -93,9 +93,9 @@ #[allow(unused_imports)] use properties::ShorthandId; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use values::computed::{Context, ToComputedValue}; #[allow(unused_imports)] @@ -285,11 +285,11 @@ #[allow(unused_imports)] use properties::style_structs; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use servo_arc::Arc; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use values::computed::{Context, ToComputedValue}; #[allow(unused_imports)] @@ -699,11 +699,11 @@ use parser::ParserContext; use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands}; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use std::fmt; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use style_traits::ToCss; @@ -992,7 +992,7 @@ // Keyword values don't make sense in the block direction; don't parse them % if "block" in name: if let Ok(${length_type}::ExtremumLength(..)) = ret { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } % endif ret.map(SpecifiedValue) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 5bf10a8b3dc..f36df1abd48 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -25,7 +25,7 @@ use properties::longhands::visibility::computed_value::T as Visibility; #[cfg(feature = "gecko")] use properties::PropertyId; use properties::{LonghandId, ShorthandId}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use smallvec::SmallVec; use std::borrow::Cow; @@ -134,6 +134,7 @@ impl TransitionProperty { /// Parse a transition-property value. pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let ident = input.expect_ident()?; match_ignore_ascii_case! { &ident, "all" => Ok(TransitionProperty::All), @@ -143,8 +144,8 @@ impl TransitionProperty { % for prop in data.longhands: "${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})), % endfor - "none" => Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()), - _ => CustomIdent::from_ident(ident, &[]).map(TransitionProperty::Unsupported), + "none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))), + _ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported), } } diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index f2eb5f2e038..3cf41d5ca0a 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -132,7 +132,7 @@ ${helpers.predefined_type("background-image", "ImageLayer", _ => Err(()), }).or_else(|()| { let horizontal: Result<_, ParseError> = RepeatKeyword::from_ident(&ident) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); let horizontal = horizontal?; let vertical = input.try(RepeatKeyword::parse).ok(); Ok(SpecifiedValue::Other(horizontal, vertical)) diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 6931eaa3f6e..845a100f98e 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -187,7 +187,7 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style', if !result.is_empty() { Ok(SpecifiedValue::Colors(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 665e6893347..8299ceade3d 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -165,7 +165,7 @@ /// Parse a display value. pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, % for value in values: "${value}" => { Ok(computed_value::T::${to_rust_ident(value)}) @@ -545,7 +545,7 @@ ${helpers.predefined_type("animation-timing-function", let number = input.expect_number()?; if number < 0.0 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Number(number)) @@ -1177,7 +1177,7 @@ ${helpers.predefined_type( _ => Err(()), }; result - .map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))) }) })?)) } @@ -1730,7 +1730,7 @@ ${helpers.predefined_type("transform-origin", }; let flag = match flag { Some(flag) if !result.contains(flag) => flag, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; result.insert(flag); } @@ -1738,7 +1738,7 @@ ${helpers.predefined_type("transform-origin", if !result.is_empty() { Ok(result) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1839,7 +1839,8 @@ ${helpers.single_keyword("-moz-orient", Ok(computed_value::T::Auto) } else { input.parse_comma_separated(|i| { - CustomIdent::from_ident(i.expect_ident()?, &[ + let location = i.current_source_location(); + CustomIdent::from_ident(location, i.expect_ident()?, &[ "will-change", "none", "all", @@ -1914,7 +1915,7 @@ ${helpers.predefined_type( pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "auto" => Ok(TOUCH_ACTION_AUTO), "none" => Ok(TOUCH_ACTION_NONE), "manipulation" => Ok(TOUCH_ACTION_MANIPULATION), diff --git a/components/style/properties/longhand/counters.mako.rs b/components/style/properties/longhand/counters.mako.rs index fa1eab1a623..a5b54fab150 100644 --- a/components/style/properties/longhand/counters.mako.rs +++ b/components/style/properties/longhand/counters.mako.rs @@ -205,7 +205,9 @@ }; match result { Some(result) => content.push(result?), - None => return Err(StyleParseError::UnexpectedFunction(name.clone()).into()) + None => return Err(input.new_custom_error( + StyleParseErrorKind::UnexpectedFunction(name.clone()) + )) } } Ok(Token::Ident(ref ident)) => { @@ -218,15 +220,15 @@ _ => false, }; if !valid { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()) + return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } Err(_) => break, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()) + Ok(t) => return Err(input.new_unexpected_token_error(t)) } } if content.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Items(content)) } @@ -332,9 +334,10 @@ let mut counters = Vec::new(); loop { + let location = input.current_source_location(); let counter_name = match input.next() { - Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(ident, &["none"])?, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?, + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, }; let counter_delta = input.try(|input| specified::parse_integer(context, input)) @@ -345,7 +348,7 @@ if !counters.is_empty() { Ok(SpecifiedValue(counters)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index ac35c271ec2..04d6c694a21 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -587,7 +587,7 @@ macro_rules! impl_gecko_keyword_conversions { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { match FontFamily::parse(input) { Ok(FontFamily::FamilyName(name)) => Ok(name), - Ok(FontFamily::Generic(_)) => Err(StyleParseError::UnspecifiedError.into()), + Ok(FontFamily::Generic(_)) => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), Err(e) => Err(e) } } @@ -744,7 +744,7 @@ ${helpers.single_keyword_system("font-variant-caps", fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { Self::from_int(input.expect_integer()?) - .map_err(|_| StyleParseError::UnspecifiedError.into()) + .map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -837,7 +837,7 @@ ${helpers.single_keyword_system("font-variant-caps", return Ok(SpecifiedValue::Keyword(kw.into())) } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "smaller" => Ok(SpecifiedValue::Smaller), "larger" => Ok(SpecifiedValue::Larger), } @@ -1082,7 +1082,7 @@ ${helpers.single_keyword_system("font-variant-caps", -> Result> { let mut result = SpecifiedValue { weight: false, style: false }; // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "none" => Ok(result), "weight" => { result.weight = true; @@ -1298,9 +1298,9 @@ ${helpers.single_keyword_system("font-kerning", let mut parsed_alternates = ParsingFlags::empty(); macro_rules! check_if_parsed( - ($flag:ident) => ( + ($input:expr, $flag:ident) => ( if parsed_alternates.contains($flag) { - return Err(StyleParseError::UnspecifiedError.into()) + return Err($input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } parsed_alternates |= $flag; ) @@ -1310,11 +1310,11 @@ ${helpers.single_keyword_system("font-kerning", match input.next()?.clone() { Token::Ident(ref ident) => { if *ident == "historical-forms" { - check_if_parsed!(HISTORICAL_FORMS); + check_if_parsed!(input, HISTORICAL_FORMS); alternates.push(VariantAlternates::HistoricalForms); Ok(()) } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } }, Token::Function(ref name) => { @@ -1322,31 +1322,34 @@ ${helpers.single_keyword_system("font-kerning", match_ignore_ascii_case! { &name, % for value in "swash stylistic ornaments annotation".split(): "${value}" => { - check_if_parsed!(${value.upper()}); - let ident = CustomIdent::from_ident(i.expect_ident()?, &[])?; + check_if_parsed!(i, ${value.upper()}); + let location = i.current_source_location(); + let ident = CustomIdent::from_ident(location, i.expect_ident()?, &[])?; alternates.push(VariantAlternates::${to_camel_case(value)}(ident)); Ok(()) }, % endfor % for value in "styleset character-variant".split(): "${value}" => { - check_if_parsed!(${to_rust_ident(value).upper()}); - let idents = i.parse_comma_separated(|i| - CustomIdent::from_ident(i.expect_ident()?, &[]))?; + check_if_parsed!(i, ${to_rust_ident(value).upper()}); + let idents = i.parse_comma_separated(|i| { + let location = i.current_source_location(); + CustomIdent::from_ident(location, i.expect_ident()?, &[]) + })?; alternates.push(VariantAlternates::${to_camel_case(value)}(idents.into_boxed_slice())); Ok(()) }, % endfor - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } }) }, - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } }) { } if parsed_alternates.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Value(VariantAlternatesList(alternates.into_boxed_slice()))) } @@ -1501,7 +1504,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1661,7 +1664,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1809,7 +1812,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -2082,10 +2085,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control- computed_value::T(atom!("")) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2105,10 +2108,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control- ::gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER as f32 } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2254,10 +2257,10 @@ ${helpers.single_keyword("-moz-math-variant", Length::new(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX)) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2287,10 +2290,10 @@ ${helpers.single_keyword("-moz-math-variant", computed_value::T(true) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2445,7 +2448,7 @@ ${helpers.single_keyword("-moz-math-variant", impl SystemFont { pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, % for font in system_fonts: "${font}" => Ok(SystemFont::${to_camel_case(font)}), % endfor diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index 115a2de202f..6b7ad377c02 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -241,7 +241,7 @@ ${helpers.single_keyword("image-rendering", // Handle | flip let angle = input.try(|input| Angle::parse(context, input)).ok(); if angle.is_none() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok(); diff --git a/components/style/properties/longhand/inherited_svg.mako.rs b/components/style/properties/longhand/inherited_svg.mako.rs index 920c12f3f44..6b49c1ed5cc 100644 --- a/components/style/properties/longhand/inherited_svg.mako.rs +++ b/components/style/properties/longhand/inherited_svg.mako.rs @@ -207,8 +207,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", let mut pos = 0; loop { - let result: Result<_, ParseError> = input.try(|i| { - try_match_ident_ignore_ascii_case! { i.expect_ident()?, + let result: Result<_, ParseError> = input.try(|input| { + try_match_ident_ignore_ascii_case! { input, "fill" => Ok(PaintOrder::Fill), "stroke" => Ok(PaintOrder::Stroke), "markers" => Ok(PaintOrder::Markers), @@ -219,7 +219,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", Ok(val) => { if (seen & (1 << val as u8)) != 0 { // don't parse the same ident twice - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } value |= (val as u8) << (pos * SHIFT); @@ -232,7 +232,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", if value == 0 { // Couldn't find any keyword - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // fill in rest @@ -293,7 +293,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let i = input.expect_ident()?; - CustomIdent::from_ident(i, &["all", "none", "auto"]) + CustomIdent::from_ident(location, i, &["all", "none", "auto"]) } diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 5a93dba2c40..e42830309d3 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -585,7 +585,7 @@ ${helpers.predefined_type( (Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape), (Some(fill), Err(_)) => KeywordValue::Fill(fill), (None, Ok(shape)) => KeywordValue::Shape(shape), - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), }; Ok(SpecifiedValue::Keyword(keyword_value)) } diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 4554f308221..8f9b8d9b103 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -188,14 +188,16 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu let mut quotes = Vec::new(); loop { + let location = input.current_source_location(); let first = match input.next() { Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, }; + let location = input.current_source_location(); let second = match input.next() { Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(e) => return Err(e.into()), }; quotes.push((first, second)) @@ -203,7 +205,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu if !quotes.is_empty() { Ok(SpecifiedValue(quotes)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 7c349be62f8..1fe1cf3910e 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -58,7 +58,7 @@ ${helpers.predefined_type( // The outline-style property accepts the same values as // border-style, except that 'hidden' is not a legal outline // style. - Err(SelectorParseError::UnexpectedIdent("hidden".into()).into()) + Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into()))) } else { Ok(result) } diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index 968052d6024..858f6f10f73 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -92,13 +92,14 @@ -> Result> { use std::ascii::AsciiExt; use style_traits::cursor::Cursor; + let location = input.current_source_location(); let ident = input.expect_ident()?; if ident.eq_ignore_ascii_case("auto") { Ok(computed_value::Keyword::Auto) } else { Cursor::from_css_keyword(&ident) .map(computed_value::Keyword::Cursor) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + .map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } } diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 1eb1582134f..45f7c077188 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -340,6 +340,7 @@ ${helpers.predefined_type("object-position", let mut dense = false; while !input.is_exhausted() { + let location = input.current_source_location(); let ident = input.expect_ident()?; let success = match_ignore_ascii_case! { &ident, "row" if value.is_none() => { @@ -357,7 +358,7 @@ ${helpers.predefined_type("object-position", _ => false }; if !success { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()); + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); } } @@ -367,7 +368,7 @@ ${helpers.predefined_type("object-position", dense: dense, }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -465,7 +466,7 @@ ${helpers.predefined_type("object-position", } TemplateAreas::from_vec(strings) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/longhand/table.mako.rs b/components/style/properties/longhand/table.mako.rs index 7d6c7aacea8..788805878b9 100644 --- a/components/style/properties/longhand/table.mako.rs +++ b/components/style/properties/longhand/table.mako.rs @@ -39,8 +39,8 @@ ${helpers.single_keyword("table-layout", "auto fixed", // never parse it, only set via presentation attribute fn parse<'i, 't>( _: &ParserContext, - _: &mut Parser<'i, 't>, + input: &mut Parser<'i, 't>, ) -> Result> { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index 586519333d6..d59063eba63 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -119,17 +119,21 @@ impl Parse for Side { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match *input.next()? { Token::Ident(ref ident) => { - try_match_ident_ignore_ascii_case! { ident, + match_ignore_ascii_case! { ident, "clip" => Ok(Side::Clip), "ellipsis" => Ok(Side::Ellipsis), + _ => Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + )) } } Token::QuotedString(ref v) => { Ok(Side::String(v.as_ref().to_owned().into_boxed_str())) } - ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => Err(location.new_unexpected_token_error(t.clone())), } } } @@ -222,6 +226,7 @@ ${helpers.single_keyword("unicode-bidi", loop { let result: Result<_, ParseError> = input.try(|input| { + let location = input.current_source_location(); match input.expect_ident() { Ok(ident) => { (match_ignore_ascii_case! { &ident, @@ -234,7 +239,9 @@ ${helpers.single_keyword("unicode-bidi", "blink" => if result.contains(BLINK) { Err(()) } else { empty = false; result.insert(BLINK); Ok(()) }, _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + }).map_err(|()| { + location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) + }) } Err(e) => return Err(e.into()) } @@ -244,7 +251,7 @@ ${helpers.single_keyword("unicode-bidi", } } - if !empty { Ok(result) } else { Err(StyleParseError::UnspecifiedError.into()) } + if !empty { Ok(result) } else { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } % if product == "servo": diff --git a/components/style/properties/longhand/ui.mako.rs b/components/style/properties/longhand/ui.mako.rs index c174360133b..5976b01b288 100644 --- a/components/style/properties/longhand/ui.mako.rs +++ b/components/style/properties/longhand/ui.mako.rs @@ -77,7 +77,7 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet" match input.expect_integer()? { 0 => Ok(computed_value::T(false)), 1 => Ok(computed_value::T(true)), - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 128bb4fbf0a..de736e7dda5 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -35,11 +35,10 @@ use parser::ParserContext; #[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont; use rule_cache::{RuleCache, RuleCacheConditions}; use selector_parser::PseudoElement; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; #[cfg(feature = "servo")] use servo_config::prefs::PREFS; use shared_lock::StylesheetGuards; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError}; -use style_traits::{PropertyDeclarationParseError, StyleParseError, ValueParseError}; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; #[cfg(feature = "servo")] use values::Either; use values::generics::text::LineHeight; @@ -153,7 +152,7 @@ macro_rules! unwrap_or_initial { pub mod shorthands { use cssparser::Parser; use parser::{Parse, ParserContext}; - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; use values::specified; <%include file="/shorthand/serialize.mako.rs" /> @@ -553,7 +552,9 @@ impl LonghandId { % if not property.derived_from: longhands::${property.ident}::parse_declared(context, input) % else: - Err(PropertyDeclarationParseError::UnknownProperty("${property.ident}".into()).into()) + Err(input.new_custom_error( + StyleParseErrorKind::UnknownProperty("${property.ident}".into()) + )) % endif } % endfor @@ -878,7 +879,7 @@ impl ShorthandId { } % endfor // 'all' accepts no value other than CSS-wide keywords - ShorthandId::All => Err(StyleParseError::UnspecifiedError.into()) + ShorthandId::All => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } } @@ -962,7 +963,7 @@ impl UnparsedValue { Some(ShorthandId::All) => { // No need to parse the 'all' shorthand as anything other than a CSS-wide // keyword, after variable substitution. - Err(SelectorParseError::UnexpectedIdent("all".into()).into()) + Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("all".into()))) } % for shorthand in data.shorthands_except_all(): Some(ShorthandId::${shorthand.camel_case}) => { @@ -1630,7 +1631,7 @@ impl PropertyDeclaration { pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration, id: PropertyId, name: CowRcStr<'i>, context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<(), PropertyDeclarationParseError<'i>> { + -> Result<(), ParseError<'i>> { assert!(declarations.is_empty()); let start = input.state(); match id { @@ -1642,8 +1643,7 @@ impl PropertyDeclaration { Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword), Err(()) => match ::custom_properties::SpecifiedValue::parse(input) { Ok(value) => DeclaredValueOwned::Value(value), - Err(e) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string().into(), - ValueParseError::from_parse_error(e))), + Err(e) => return Err(StyleParseErrorKind::new_invalid(name, e)), } }; declarations.push(PropertyDeclaration::Custom(property_name, value)); @@ -1662,8 +1662,7 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(e)) + StyleParseErrorKind::new_invalid(name, e) })?; Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue { css: css.into_owned(), @@ -1672,8 +1671,7 @@ impl PropertyDeclaration { from_shorthand: None, }))) } else { - Err(PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(err))) + Err(StyleParseErrorKind::new_invalid(name, err)) } }) }).map(|declaration| { @@ -1701,8 +1699,7 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(e)) + StyleParseErrorKind::new_invalid(name, e) })?; let unparsed = Arc::new(UnparsedValue { css: css.into_owned(), @@ -1721,8 +1718,7 @@ impl PropertyDeclaration { } Ok(()) } else { - Err(PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(err))) + Err(StyleParseErrorKind::new_invalid(name, err)) } }) } diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs index 32cf30b6db6..3f135e67ce8 100644 --- a/components/style/properties/shorthand/background.mako.rs +++ b/components/style/properties/shorthand/background.mako.rs @@ -47,7 +47,7 @@ // background-color can only be in the last element, so if it // is parsed anywhere before, the value is invalid. if background_color.is_some() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } % for name in "image position repeat size attachment origin clip".split(): @@ -112,7 +112,7 @@ % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } })?; @@ -217,7 +217,7 @@ Ok(()) })?; if !any { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index 81093d91b3c..5a7eaf89f6d 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -83,7 +83,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) style.unwrap_or(BorderStyle::none), width.unwrap_or(BorderSideWidth::Medium))) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -276,7 +276,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) border_image_outset::parse(context, input) }).ok(); if w.is_none() && o.is_none() { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok((w, o)) @@ -312,7 +312,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } }); result?; diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index 19c8e0e7c1e..94510e12c1f 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -14,8 +14,8 @@ pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { % if product == "gecko": - let moz_kw_found = input.try(|i| { - try_match_ident_ignore_ascii_case! { i.expect_ident()?, + let moz_kw_found = input.try(|input| { + try_match_ident_ignore_ascii_case! { input, "-moz-scrollbars-horizontal" => { Ok(expanded! { overflow_x: SpecifiedValue::scroll, @@ -141,7 +141,7 @@ macro_rules! try_parse_one { Some(transition_property::single_value::get_initial_specified_value())), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -158,7 +158,7 @@ macro_rules! try_parse_one { // If there is more than one item, and any of transitions has 'none', // then it's invalid. Othersize, leave propertys to be empty (which // means "transition-property: none"); - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } % for prop in "duration timing_function delay".split(): @@ -269,7 +269,7 @@ macro_rules! try_parse_one { // If nothing is parsed, this is an invalid entry. if parsed == 0 { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(SingleAnimation { % for prop in props: diff --git a/components/style/properties/shorthand/column.mako.rs b/components/style/properties/shorthand/column.mako.rs index 166de6e34d1..cf1071def1e 100644 --- a/components/style/properties/shorthand/column.mako.rs +++ b/components/style/properties/shorthand/column.mako.rs @@ -44,7 +44,7 @@ let values = autos + column_count.iter().len() + column_width.iter().len(); if values == 0 || values > 2 { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(expanded! { column_count: unwrap_or_initial!(column_count), @@ -89,7 +89,7 @@ column_rule_color: unwrap_or_initial!(column_rule_color), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index 0bd11277e74..b06f03a74e2 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -98,7 +98,7 @@ } if size.is_none() || (count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let line_height = if input.try(|input| input.expect_delim('/')).is_ok() { Some(LineHeight::parse(context, input)?) @@ -262,7 +262,7 @@ loop { if input.try(|input| input.expect_ident_matching("normal")).is_ok() || input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } % for prop in sub_properties: if ${prop}.is_none() { @@ -278,7 +278,7 @@ } if !has_custom_value { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/shorthand/inherited_text.mako.rs b/components/style/properties/shorthand/inherited_text.mako.rs index 784caf43d2f..664d5238d57 100644 --- a/components/style/properties/shorthand/inherited_text.mako.rs +++ b/components/style/properties/shorthand/inherited_text.mako.rs @@ -36,7 +36,7 @@ text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -78,7 +78,7 @@ _webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/shorthand/list.mako.rs b/components/style/properties/shorthand/list.mako.rs index c92d5c7170e..9cdeea469eb 100644 --- a/components/style/properties/shorthand/list.mako.rs +++ b/components/style/properties/shorthand/list.mako.rs @@ -21,7 +21,7 @@ if input.try(|input| input.expect_ident_matching("none")).is_ok() { nones = nones + 1; if nones > 2 { - return Err(SelectorParseError::UnexpectedIdent("none".into()).into()) + return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("none".into()))) } any = true; continue @@ -106,7 +106,7 @@ list_style_type: unwrap_or_initial!(list_style_type), }) } - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } diff --git a/components/style/properties/shorthand/mask.mako.rs b/components/style/properties/shorthand/mask.mako.rs index b0e298317fe..ebf9f215f91 100644 --- a/components/style/properties/shorthand/mask.mako.rs +++ b/components/style/properties/shorthand/mask.mako.rs @@ -108,7 +108,7 @@ % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } })?; @@ -203,7 +203,7 @@ Ok(()) })?; if any == false { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/components/style/properties/shorthand/outline.mako.rs b/components/style/properties/shorthand/outline.mako.rs index 5d816965fae..0fe8a11118b 100644 --- a/components/style/properties/shorthand/outline.mako.rs +++ b/components/style/properties/shorthand/outline.mako.rs @@ -50,7 +50,7 @@ outline_width: unwrap_or_initial!(outline_width, width), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index 6a4661c4f56..82e0ef3cbad 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -32,7 +32,7 @@ } if direction.is_none() && wrap.is_none() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(expanded! { flex_direction: unwrap_or_initial!(flex_direction, direction), @@ -87,7 +87,7 @@ } if grow.is_none() && basis.is_none() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(expanded! { flex_grow: grow.unwrap_or(NonNegativeNumber::new(1.0)), @@ -309,7 +309,7 @@ } let template_areas = TemplateAreas::from_vec(strings) - .map_err(|()| StyleParseError::UnspecifiedError)?; + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?; let template_rows = TrackList { list_type: TrackListType::Normal, values: values, @@ -321,7 +321,7 @@ let value = GridTemplateComponent::parse_without_none(context, input)?; if let GenericGridTemplateComponent::TrackList(ref list) = value { if list.list_type != TrackListType::Explicit { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -340,7 +340,7 @@ if list.line_names[0].is_empty() { list.line_names[0] = first_line_names; // won't panic } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } } @@ -501,7 +501,7 @@ autoflow: flow, dense: dense, } - }).ok_or(StyleParseError::UnspecifiedError.into()) + }).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) { @@ -617,12 +617,12 @@ -> Result> { let align = align_content::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| justify_content::parse(context, input)) .unwrap_or(justify_content::SpecifiedValue::from(align)); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { @@ -653,11 +653,11 @@ -> Result> { let align = AlignJustifySelf::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| AlignJustifySelf::parse(context, input)).unwrap_or(align.clone()); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { @@ -695,12 +695,12 @@ -> Result> { let align = AlignItems::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| JustifyItems::parse(context, input)) .unwrap_or(JustifyItems::from(align)); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/components/style/properties/shorthand/text.mako.rs b/components/style/properties/shorthand/text.mako.rs index bd119f7cd8a..49c3f80fc90 100644 --- a/components/style/properties/shorthand/text.mako.rs +++ b/components/style/properties/shorthand/text.mako.rs @@ -48,7 +48,7 @@ } if !any { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 8d99b8ba81e..137058f3826 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -14,7 +14,7 @@ use parser::ParserContext; use properties::{ComputedValues, StyleBuilder}; use properties::longhands::font_size; use rule_cache::RuleCacheConditions; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::cell::RefCell; use std::fmt; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; @@ -198,7 +198,7 @@ impl Expression { "width" => { ExpressionKind::Width(Range::Eq(specified::Length::parse_non_negative(context, input)?)) }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) })) }) } diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 201fbd1b6fe..887503f9a11 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -8,7 +8,7 @@ use {Atom, Prefix, Namespace, LocalName, CaseSensitivityExt}; use attr::{AttrIdentifier, AttrValue}; -use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr}; +use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr, SourceLocation}; use dom::{OpaqueNode, TElement, TNode}; use element_state::ElementState; use fnv::FnvHashMap; @@ -19,14 +19,14 @@ use properties::longhands::display::computed_value as display; use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser}; use selectors::Element; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; -use selectors::parser::{SelectorMethods, SelectorParseError}; +use selectors::parser::{SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::ascii::AsciiExt; use std::fmt; use std::fmt::Debug; use std::mem; use std::ops::{Deref, DerefMut}; -use style_traits::{ParseError, StyleParseError}; +use style_traits::{ParseError, StyleParseErrorKind}; /// A pseudo-element, both public and private. /// @@ -395,9 +395,9 @@ impl ::selectors::SelectorImpl for SelectorImpl { impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { type Impl = SelectorImpl; - type Error = StyleParseError<'i>; + type Error = StyleParseErrorKind<'i>; - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result> { use self::NonTSPseudoClass::*; let pseudo_class = match_ignore_ascii_case! { &name, @@ -418,12 +418,13 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { "visited" => Visited, "-servo-nonzero-border" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent( - "-servo-nonzero-border".into()).into()); + return Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("-servo-nonzero-border".into()) + )) } ServoNonZeroBorder }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()), + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))), }; Ok(pseudo_class) @@ -440,17 +441,18 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { } "-servo-case-sensitive-type-attr" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()); + return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))); } ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref())) } - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; Ok(pseudo_class) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result> { + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { use self::PseudoElement::*; let pseudo_element = match_ignore_ascii_case! { &name, "before" => Before, @@ -458,77 +460,77 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { "selection" => Selection, "-servo-details-summary" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } DetailsSummary }, "-servo-details-content" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } DetailsContent }, "-servo-text" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoText }, "-servo-input-text" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInputText }, "-servo-table-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoTableWrapper }, "-servo-anonymous-table-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableWrapper }, "-servo-anonymous-table" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTable }, "-servo-anonymous-table-row" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableRow }, "-servo-anonymous-table-cell" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableCell }, "-servo-anonymous-block" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousBlock }, "-servo-inline-block-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInlineBlockWrapper }, "-servo-input-absolute" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInlineAbsolute }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index e85d0c31496..e407aa1b3fa 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -6,7 +6,7 @@ //! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4. //! We implement the prefixed `@-moz-document`. -use cssparser::{Parser, Token, SourceLocation, BasicParseError}; +use cssparser::{Parser, Token, SourceLocation}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use media_queries::Device; @@ -14,7 +14,7 @@ use parser::{Parse, ParserContext}; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use stylesheets::CssRules; use values::specified::url::SpecifiedUrl; @@ -100,10 +100,11 @@ macro_rules! parse_quoted_or_unquoted_string { $input.parse_nested_block(|input| { let start = input.position(); input.parse_entirely(|input| { + let location = input.current_source_location(); match input.next() { Ok(&Token::QuotedString(ref value)) => Ok($url_matching_function(value.as_ref().to_owned())), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } }).or_else(|_: ParseError| { @@ -129,7 +130,7 @@ impl UrlMatchingFunction { } else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { Ok(UrlMatchingFunction::Url(url)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/stylesheets/font_feature_values_rule.rs b/components/style/stylesheets/font_feature_values_rule.rs index e2adac1fc8b..932ac08e9b3 100644 --- a/components/style/stylesheets/font_feature_values_rule.rs +++ b/components/style/stylesheets/font_feature_values_rule.rs @@ -8,7 +8,7 @@ use Atom; use computed_values::font_family::FamilyName; -use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser}; +use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier}; use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] @@ -16,10 +16,9 @@ use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry; #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray}; use parser::{ParserContext, ParserErrorContext, Parse}; -use selectors::parser::SelectorParseError; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ParseError, StyleParseError, ToCss}; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; use stylesheets::CssRuleType; /// A @font-feature-values block declaration. @@ -59,9 +58,10 @@ pub struct SingleValue(pub u32); impl Parse for SingleValue { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match *input.next()? { Token::Number { int_value: Some(v), .. } if v >= 0 => Ok(SingleValue(v as u32)), - ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => Err(location.new_unexpected_token_error(t.clone())), } } } @@ -87,16 +87,18 @@ pub struct PairValues(pub u32, pub Option); impl Parse for PairValues { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let first = match *input.next()? { Token::Number { int_value: Some(a), .. } if a >= 0 => a as u32, - ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => return Err(location.new_unexpected_token_error(t.clone())), }; + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(b), .. }) if b >= 0 => { Ok(PairValues(first, Some(b as u32))) } // It can't be anything other than number. - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), // It can be just one value. Err(_) => Ok(PairValues(first, None)) } @@ -136,18 +138,19 @@ impl Parse for VectorValues { -> Result> { let mut vec = vec![]; loop { + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(a), .. }) if a >= 0 => { vec.push(a as u32); }, // It can't be anything other than number. - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, } } if vec.len() == 0 { - return Err(BasicParseError::EndOfInput.into()); + return Err(input.new_error(BasicParseErrorKind::EndOfInput)); } Ok(VectorValues(vec)) @@ -197,14 +200,14 @@ impl<'a, 'b, 'i, T> AtRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T> where T: Parse { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -271,9 +274,10 @@ macro_rules! font_feature_values_blocks { rule: &mut rule, }); while let Some(result) = iter.next() { - if let Err(err) = result { - let error = ContextualParseError::UnsupportedRule(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + if let Err((error, slice)) = result { + let location = error.location; + let error = ContextualParseError::UnsupportedRule(slice, error); + context.log_css_error(error_context, location, error); } } } @@ -387,24 +391,24 @@ macro_rules! font_feature_values_blocks { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type Prelude = (); type QualifiedRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type PreludeNoBlock = (); type PreludeBlock = BlockType; type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>(&mut self, name: CowRcStr<'i>, - _input: &mut Parser<'i, 't>) + input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { match_ignore_ascii_case! { &*name, $( $name => Ok(AtRuleType::WithBlock(BlockType::$ident_camel)), )* - _ => Err(BasicParseError::AtRuleBodyInvalid.into()), + _ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)), } } @@ -424,10 +428,12 @@ macro_rules! font_feature_values_blocks { let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { + if let Err((error, slice)) = declaration { + let location = error.location; let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration( - err.slice, err.error); - self.context.log_css_error(self.error_context, err.location, error); + slice, error + ); + self.context.log_css_error(self.error_context, location, error); } } }, diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs index 8541f58d248..97fcd6d3bf2 100644 --- a/components/style/stylesheets/keyframes_rule.rs +++ b/components/style/stylesheets/keyframes_rule.rs @@ -12,12 +12,10 @@ use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, Prop use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration}; use properties::LonghandIdSet; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; -use selectors::parser::SelectorParseError; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard}; use std::fmt; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError}; -use style_traits::PropertyDeclarationParseError; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind}; use stylesheets::{CssRuleType, StylesheetContents}; use stylesheets::rule_parser::VendorPrefix; use values::{KeyframesName, serialize_percentage}; @@ -137,7 +135,7 @@ impl KeyframePercentage { if percentage >= 0. && percentage <= 1. { KeyframePercentage::new(percentage) } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } }; @@ -500,7 +498,7 @@ impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Arc>; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } /// A wrapper to wraps the KeyframeSelector with its source location @@ -512,7 +510,7 @@ struct KeyframeSelectorParserPrelude { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> { type Prelude = KeyframeSelectorParserPrelude; type QualifiedRule = Arc>; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result> { let start_position = input.position(); @@ -525,8 +523,9 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars }) }, Err(e) => { + let location = e.location; let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone()); - self.context.log_css_error(self.error_context, start_location, error); + self.context.log_css_error(self.error_context, location, error); Err(e) } } @@ -552,10 +551,11 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars Ok(()) => { block.extend(iter.parser.declarations.drain(), Importance::Normal); } - Err(err) => { + Err((error, slice)) => { iter.parser.declarations.clear(); - let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error); - context.log_css_error(self.error_context, err.location, error); + let location = error.location; + let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error); + context.log_css_error(self.error_context, location, error); } } // `parse_important` is not called here, `!important` is not allowed in keyframe blocks. @@ -578,25 +578,26 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for KeyframeDeclarationParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { let property_context = PropertyParserContext::new(self.context); - let id = PropertyId::parse(&name, Some(&property_context)) - .map_err(|()| PropertyDeclarationParseError::UnknownProperty(name.clone()))?; + let id = PropertyId::parse(&name, Some(&property_context)).map_err(|()| { + input.new_custom_error(StyleParseErrorKind::UnknownProperty(name.clone())) + })?; match PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) { Ok(()) => { // In case there is still unparsed text in the declaration, we should roll back. input.expect_exhausted().map_err(|e| e.into()) } - Err(_e) => Err(StyleParseError::UnspecifiedError.into()) + Err(e) => Err(e.into()) } } } diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs index 30d1219dab1..2c25d64e8c8 100644 --- a/components/style/stylesheets/rule_parser.rs +++ b/components/style/stylesheets/rule_parser.rs @@ -8,7 +8,7 @@ use {Namespace, Prefix}; use computed_values::font_family::FamilyName; use counter_style::{parse_counter_style_body, parse_counter_style_name}; use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; -use cssparser::{CowRcStr, SourceLocation, BasicParseError}; +use cssparser::{CowRcStr, SourceLocation, BasicParseError, BasicParseErrorKind}; use error_reporting::{ContextualParseError, ParseErrorReporter}; use font_face::parse_font_face_block; use media_queries::{parse_media_query_list, MediaList}; @@ -16,11 +16,10 @@ use parser::{Parse, ParserContext, ParserErrorContext}; use properties::parse_property_declaration_list; use selector_parser::{SelectorImpl, SelectorParser}; use selectors::SelectorList; -use selectors::parser::SelectorParseError; use servo_arc::Arc; use shared_lock::{Locked, SharedRwLock}; use str::starts_with_ignore_ascii_case; -use style_traits::{StyleParseError, ParseError}; +use style_traits::{StyleParseErrorKind, ParseError}; use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader}; use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule}; use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule}; @@ -160,7 +159,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeBlock = AtRuleBlockPrelude; type AtRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, @@ -173,7 +172,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, if self.state > State::Imports { // "@import must be before any rule but @charset" self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedImportRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedImportRule)) } let url_string = input.expect_url_or_string()?.as_ref().to_owned(); @@ -190,15 +189,16 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, if self.state > State::Namespaces { // "@namespace must be before any rule but @charset and @import" self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedNamespaceRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedNamespaceRule)) } let prefix = input.try(|i| i.expect_ident_cloned()) .map(|s| Prefix::from(s.as_ref())).ok(); let maybe_namespace = match input.expect_url_or_string() { Ok(url_or_string) => url_or_string, - Err(BasicParseError::UnexpectedToken(t)) => - return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()), + Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => { + return Err(location.new_custom_error(StyleParseErrorKind::UnexpectedTokenWithinNamespace(t))) + } Err(e) => return Err(e.into()), }; let url = Namespace::from(maybe_namespace.as_ref()); @@ -209,7 +209,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, // anything left is invalid. "charset" => { self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedCharsetRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedCharsetRule)) } _ => {} } @@ -279,7 +279,7 @@ pub struct QualifiedRuleParserPrelude { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> { type Prelude = QualifiedRuleParserPrelude; type QualifiedRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; #[inline] fn parse_prelude<'t>( @@ -331,9 +331,10 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> { while let Some(result) = iter.next() { match result { Ok(rule) => rules.push(rule), - Err(err) => { - let error = ContextualParseError::UnsupportedRule(err.slice, err.error); - self.context.log_css_error(self.error_context, err.location, error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::UnsupportedRule(slice, error); + self.context.log_css_error(self.error_context, location, error); } } } @@ -345,7 +346,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeBlock = AtRuleBlockPrelude; type AtRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, @@ -371,7 +372,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a "font-feature-values" => { if !cfg!(feature = "gecko") { // Support for this rule is not fully implemented in Servo yet. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let family_names = parse_family_name_list(self.context, input)?; Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names, location))) @@ -379,14 +380,14 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a "counter-style" => { if !cfg!(feature = "gecko") { // Support for this rule is not fully implemented in Servo yet. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let name = parse_counter_style_name(input)?; // ASCII-case-insensitive matches for "decimal" and "disc". // The name is already lower-cased by `parse_counter_style_name` // so we can use == here. if name.0 == atom!("decimal") || name.0 == atom!("disc") { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::CounterStyle(name))) }, @@ -394,7 +395,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if viewport_rule::enabled() { Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Viewport)) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, "keyframes" | "-webkit-keyframes" | "-moz-keyframes" => { @@ -408,7 +409,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if cfg!(feature = "servo") && prefix.as_ref().map_or(false, |p| matches!(*p, VendorPrefix::Moz)) { // Servo should not support @-moz-keyframes. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let name = KeyframesName::parse(self.context, input)?; @@ -418,7 +419,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if cfg!(feature = "gecko") { Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Page(location))) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, "-moz-document" => { @@ -426,10 +427,10 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a let cond = DocumentCondition::parse(self.context, input)?; Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location))) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, - _ => Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + _ => Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } } @@ -548,7 +549,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> { type Prelude = QualifiedRuleParserPrelude; type QualifiedRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs index 1b5d2285af6..e8d22e19bb2 100644 --- a/components/style/stylesheets/stylesheet.rs +++ b/components/style/stylesheets/stylesheet.rs @@ -394,10 +394,11 @@ impl Stylesheet { break; } }, - Err(err) => { - let error = ContextualParseError::InvalidRule(err.slice, err.error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::InvalidRule(slice, error); iter.parser.context.log_css_error(&iter.parser.error_context, - err.location, error); + location, error); } } } diff --git a/components/style/stylesheets/supports_rule.rs b/components/style/stylesheets/supports_rule.rs index 07f42c4c5c3..e378a49b9bb 100644 --- a/components/style/stylesheets/supports_rule.rs +++ b/components/style/stylesheets/supports_rule.rs @@ -4,17 +4,17 @@ //! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports) -use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput}; use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token}; +use cssparser::{ParseError as CssParseError, ParserInput}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use parser::ParserContext; use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError}; use stylesheets::{CssRuleType, CssRules}; /// An [`@supports`][supports] rule. @@ -104,6 +104,7 @@ impl SupportsCondition { let in_parens = SupportsCondition::parse_in_parens(input)?; + let location = input.current_source_location(); let (keyword, wrapper) = match input.next() { Err(_) => { // End of input @@ -113,10 +114,10 @@ impl SupportsCondition { match_ignore_ascii_case! { &ident, "and" => ("and", SupportsCondition::And as fn(_) -> _), "or" => ("or", SupportsCondition::Or as fn(_) -> _), - _ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()) + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } - Ok(t) => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))) + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())) }; let mut conditions = Vec::with_capacity(2); @@ -138,6 +139,7 @@ impl SupportsCondition { // but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases. while input.try(Parser::expect_whitespace).is_ok() {} let pos = input.position(); + let location = input.current_source_location(); // FIXME: remove clone() when lifetimes are non-lexical match input.next()?.clone() { Token::ParenthesisBlock => { @@ -149,7 +151,7 @@ impl SupportsCondition { } } Token::Function(_) => {} - t => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t))), + t => return Err(location.new_unexpected_token_error(t)), } input.parse_nested_block(|i| consume_any_value(i))?; Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned())) @@ -258,18 +260,18 @@ impl Declaration { let mut input = ParserInput::new(&self.0); let mut input = Parser::new(&mut input); - input.parse_entirely(|input| { + input.parse_entirely(|input| -> Result<(), CssParseError<()>> { let prop = input.expect_ident().unwrap().as_ref().to_owned(); input.expect_colon().unwrap(); let property_context = PropertyParserContext::new(&context); let id = PropertyId::parse(&prop, Some(&property_context)) - .map_err(|_| StyleParseError::UnspecifiedError)?; + .map_err(|()| input.new_custom_error(()))?; let mut declarations = SourcePropertyDeclaration::new(); input.parse_until_before(Delimiter::Bang, |input| { PropertyDeclaration::parse_into(&mut declarations, id, prop.into(), &context, input) - .map_err(|e| StyleParseError::PropertyDeclaration(e).into()) + .map_err(|_| input.new_custom_error(())) })?; let _ = input.try(parse_important); Ok(()) diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index d0263e1366d..635fe9ca82c 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -18,7 +18,7 @@ use media_queries::Device; use parser::{ParserContext, ParserErrorContext}; use properties::StyleBuilder; use rule_cache::RuleCacheConditions; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -26,7 +26,7 @@ use std::cell::RefCell; use std::fmt; use std::iter::Enumerate; use std::str::Chars; -use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError}; +use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom}; use stylesheets::{StylesheetInDocument, Origin}; use values::computed::{Context, ToComputedValue}; @@ -276,12 +276,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for ViewportRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Vec; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> { type Declaration = Vec; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { @@ -323,7 +323,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> { "max-zoom" => ok!(MaxZoom(Zoom::parse)), "user-zoom" => ok!(UserZoom(UserZoom::parse)), "orientation" => ok!(Orientation(Orientation::parse)), - _ => Err(SelectorParseError::UnexpectedIdent(name.clone()).into()), + _ => Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))), } } } @@ -368,9 +368,10 @@ impl ViewportRule { cascade.add(Cow::Owned(declarations)) } } - Err(err) => { - let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(slice, error); + context.log_css_error(error_context, location, error); } } } diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index a8814a6f825..04c643a4b50 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -8,7 +8,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::{fmt, mem, usize}; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::{CSSFloat, CustomIdent, serialize_dimension}; use values::computed::{Context, ToComputedValue}; use values::specified; @@ -88,9 +88,10 @@ impl Parse for GridLine { let mut val_before_span = false; for _ in 0..3 { // Maximum possible entities for + let location = input.current_source_location(); if input.try(|i| i.expect_ident_matching("span")).is_ok() { if grid_line.is_span { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if grid_line.line_num.is_some() || grid_line.ident.is_some() { @@ -101,31 +102,31 @@ impl Parse for GridLine { } else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) { // FIXME(emilio): Probably shouldn't reject if it's calc()... if i.value() == 0 || val_before_span || grid_line.line_num.is_some() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } grid_line.line_num = Some(i); } else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) { if val_before_span || grid_line.ident.is_some() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } - grid_line.ident = Some(CustomIdent::from_ident(&name, &[])?); + grid_line.ident = Some(CustomIdent::from_ident(location, &name, &[])?); } else { break } } if grid_line.is_auto() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if grid_line.is_span { if let Some(i) = grid_line.line_num { if i.value() <= 0 { // disallow negative integers for grid spans - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } else if grid_line.ident.is_none() { // integer could be omitted - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -369,7 +370,7 @@ impl Parse for RepeatCount { } Ok(RepeatCount::Number(i)) } else { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "auto-fill" => Ok(RepeatCount::AutoFill), "auto-fit" => Ok(RepeatCount::AutoFit), } @@ -612,14 +613,14 @@ impl Parse for LineNameList { RepeatCount::AutoFill if fill_idx.is_none() => { // `repeat(autof-fill, ..)` should have just one line name. if names_list.len() != 1 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let names = names_list.pop().unwrap(); line_names.push(names); fill_idx = Some(line_names.len() as u32 - 1); }, - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } else if let Ok(names) = input.try(parse_line_names) { line_names.push(names); diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 4603523d920..7491337eaf9 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -9,7 +9,7 @@ use counter_style::{Symbols, parse_counter_style_name}; use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use super::CustomIdent; pub mod background; @@ -114,16 +114,16 @@ impl Parse for CounterStyleOrNone { // numeric system. if (symbols_type == SymbolsType::Alphabetic || symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } // Identifier is not allowed in symbols() function. if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) }); } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -170,13 +170,14 @@ impl Parse for FontSettingTag { let u_tag; { + let location = input.current_source_location(); let tag = input.expect_string()?; // allowed strings of length 4 containing chars: if tag.len() != 4 || tag.chars().any(|c| c < ' ' || c > '~') { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let mut raw = Cursor::new(tag.as_bytes()); @@ -248,7 +249,7 @@ impl Parse for FontSettingTagInt { if value >= 0 { Ok(FontSettingTagInt(value as u32)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) { // on is an alias for '1' diff --git a/components/style/values/generics/svg.rs b/components/style/values/generics/svg.rs index 24444da8894..49efbe40256 100644 --- a/components/style/values/generics/svg.rs +++ b/components/style/values/generics/svg.rs @@ -7,7 +7,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; -use style_traits::{ParseError, StyleParseError, ToCss}; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; use values::{Either, None_}; use values::computed::NumberOrPercentage; use values::computed::length::LengthOrPercentage; @@ -54,7 +54,7 @@ pub enum SVGPaintKind { impl SVGPaintKind { /// Parse a keyword value only fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "none" => Ok(SVGPaintKind::None), "context-fill" => Ok(SVGPaintKind::ContextFill), "context-stroke" => Ok(SVGPaintKind::ContextStroke), @@ -104,7 +104,7 @@ impl Parse for SVGPaint Parse for if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) { return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop)); } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index f338cb357c0..02e2d8e82cf 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -9,13 +9,13 @@ #![deny(missing_docs)] use Atom; -pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CowRcStr}; +pub use cssparser::{RGBA, Token, Parser, serialize_identifier, CowRcStr, SourceLocation}; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::ascii::AsciiExt; use std::fmt::{self, Debug}; use std::hash; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; pub mod animated; pub mod computed; @@ -57,9 +57,9 @@ pub enum Impossible {} impl Parse for Impossible { fn parse<'i, 't>( _context: &ParserContext, - _input: &mut Parser<'i, 't>) + input: &mut Parser<'i, 't>) -> Result> { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -103,16 +103,17 @@ pub struct CustomIdent(pub Atom); impl CustomIdent { /// Parse an already-tokenizer identifier - pub fn from_ident<'i>(ident: &CowRcStr<'i>, excluding: &[&str]) -> Result> { + pub fn from_ident<'i>(location: SourceLocation, ident: &CowRcStr<'i>, excluding: &[&str]) + -> Result> { let valid = match_ignore_ascii_case! { ident, "initial" | "inherit" | "unset" | "default" => false, _ => true }; if !valid { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()); + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); } if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) { - Err(StyleParseError::UnspecifiedError.into()) + Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(CustomIdent(Atom::from(ident.as_ref()))) } @@ -139,7 +140,8 @@ pub enum KeyframesName { impl KeyframesName { /// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name pub fn from_ident(value: &str) -> Self { - let custom_ident = CustomIdent::from_ident(&value.into(), &["none"]).ok(); + let location = SourceLocation { line: 0, column: 0 }; + let custom_ident = CustomIdent::from_ident(location, &value.into(), &["none"]).ok(); match custom_ident { Some(ident) => KeyframesName::Ident(ident), None => KeyframesName::QuotedString(value.into()), @@ -182,10 +184,11 @@ impl hash::Hash for KeyframesName { impl Parse for KeyframesName { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match input.next() { - Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)), + Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(location, s, &["none"])?)), Ok(&Token::QuotedString(ref s)) => Ok(KeyframesName::QuotedString(Atom::from(s.as_ref()))), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index 9e2281bba43..4996ed6f5df 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -9,10 +9,10 @@ use cssparser::Parser; use gecko_bindings::structs; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::ascii::AsciiExt; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; bitflags! { /// Constants shared by multiple CSS Box Alignment properties @@ -201,7 +201,7 @@ impl Parse for AlignJustifyContent { } return Ok(AlignJustifyContent::new(fallback)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -239,7 +239,7 @@ impl Parse for AlignJustifySelf { if let Ok(value) = input.try(parse_overflow_self_position) { return Ok(AlignJustifySelf(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -277,7 +277,7 @@ impl Parse for AlignItems { if let Ok(value) = input.try(parse_overflow_self_position) { return Ok(AlignItems(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -326,7 +326,7 @@ impl Parse for JustifyItems { if let Ok(value) = parse_overflow_self_position(input) { return Ok(JustifyItems(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -351,7 +351,7 @@ fn parse_auto_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>) return Ok(baseline); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "auto" => Ok(ALIGN_AUTO), "normal" => Ok(ALIGN_NORMAL), "stretch" => Ok(ALIGN_STRETCH), @@ -364,7 +364,7 @@ fn parse_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result Ok(ALIGN_NORMAL), "stretch" => Ok(ALIGN_STRETCH), } @@ -383,7 +383,7 @@ fn parse_normal_or_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "baseline" => Ok(ALIGN_BASELINE), "first" => { input.expect_ident_matching("baseline")?; @@ -398,7 +398,7 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "stretch" => Ok(ALIGN_STRETCH), "space-between" => Ok(ALIGN_SPACE_BETWEEN), "space-around" => Ok(ALIGN_SPACE_AROUND), @@ -421,12 +421,12 @@ fn parse_overflow_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result return Ok(overflow | content) } } - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "start" => Ok(ALIGN_START), "end" => Ok(ALIGN_END), "flex-start" => Ok(ALIGN_FLEX_START), @@ -439,7 +439,7 @@ fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_overflow_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "safe" => Ok(ALIGN_SAFE), "unsafe" => Ok(ALIGN_UNSAFE), } @@ -460,12 +460,12 @@ fn parse_overflow_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "start" => Ok(ALIGN_START), "end" => Ok(ALIGN_END), "flex-start" => Ok(ALIGN_FLEX_START), @@ -480,7 +480,9 @@ fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result(input: &mut Parser<'i, 't>) -> Result> { + let a_location = input.current_source_location(); let a = input.expect_ident()?.clone(); + let b_location = input.current_source_location(); let b = input.expect_ident()?; if a.eq_ignore_ascii_case("legacy") { (match_ignore_ascii_case! { &b, @@ -488,15 +490,15 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result Ok(ALIGN_LEGACY | ALIGN_RIGHT), "center" => Ok(ALIGN_LEGACY | ALIGN_CENTER), _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(b.clone()).into()) + }).map_err(|()| b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone()))) } else if b.eq_ignore_ascii_case("legacy") { (match_ignore_ascii_case! { &a, "left" => Ok(ALIGN_LEGACY | ALIGN_LEFT), "right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT), "center" => Ok(ALIGN_LEGACY | ALIGN_CENTER), _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(a).into()) + }).map_err(|()| a_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(a))) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(a_location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/components/style/values/specified/angle.rs b/components/style/values/specified/angle.rs index c1cb7505bf1..11ecd53f77e 100644 --- a/components/style/values/specified/angle.rs +++ b/components/style/values/specified/angle.rs @@ -4,7 +4,7 @@ //! Specified angles. -use cssparser::{Parser, Token, BasicParseError}; +use cssparser::{Parser, Token}; use parser::{ParserContext, Parse}; use std::ascii::AsciiExt; use std::fmt; @@ -112,7 +112,7 @@ impl Parse for Angle { return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into()) + }.map_err(|()| input.new_unexpected_token_error(token.clone())) } } @@ -155,6 +155,6 @@ impl Angle { return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into()) + }.map_err(|()| input.new_unexpected_token_error(token.clone())) } } diff --git a/components/style/values/specified/background.rs b/components/style/values/specified/background.rs index c358feefaec..dd9949adf26 100644 --- a/components/style/values/specified/background.rs +++ b/components/style/values/specified/background.rs @@ -6,7 +6,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use style_traits::ParseError; use values::generics::background::BackgroundSize as GenericBackgroundSize; use values::specified::length::LengthOrPercentageOrAuto; @@ -22,12 +22,13 @@ impl Parse for BackgroundSize { .unwrap_or(LengthOrPercentageOrAuto::Auto); return Ok(GenericBackgroundSize::Explicit { width, height }); } + let location = input.current_source_location(); let ident = input.expect_ident()?; (match_ignore_ascii_case! { &ident, "cover" => Ok(GenericBackgroundSize::Cover), "contain" => Ok(GenericBackgroundSize::Contain), _ => Err(()), - }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + }).map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index cabed5994ed..3332ce94d6a 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -11,7 +11,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::borrow::Cow; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::computed::Percentage; use values::generics::basic_shape::{Circle as GenericCircle}; use values::generics::basic_shape::{ClippingShape as GenericClippingShape, Ellipse as GenericEllipse}; @@ -81,7 +81,7 @@ impl Parse for ShapeSource Ok(GeometryBox::FillBox), "stroke-box" => Ok(GeometryBox::StrokeBox), "view-box" => Ok(GeometryBox::ViewBox), @@ -101,6 +101,7 @@ impl Parse for GeometryBox { impl Parse for BasicShape { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let function = input.expect_function()?.clone(); input.parse_nested_block(move |i| { (match_ignore_ascii_case! { &function, @@ -109,7 +110,7 @@ impl Parse for BasicShape { "ellipse" => return Ellipse::parse_function_arguments(context, i).map(GenericBasicShape::Ellipse), "polygon" => return Polygon::parse_function_arguments(context, i).map(GenericBasicShape::Polygon), _ => Err(()) - }).map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into()) + }).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))) }) } } @@ -229,7 +230,7 @@ impl Parse for ShapeRadius { return Ok(GenericShapeRadius::Length(lop)) } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "closest-side" => Ok(GenericShapeRadius::ClosestSide), "farthest-side" => Ok(GenericShapeRadius::FarthestSide), } diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs index aef0b0b2854..2223648c1a5 100644 --- a/components/style/values/specified/border.rs +++ b/components/style/values/specified/border.rs @@ -62,7 +62,7 @@ impl BorderSideWidth { if let Ok(length) = input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) { return Ok(BorderSideWidth::Length(length)); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "thin" => Ok(BorderSideWidth::Thin), "medium" => Ok(BorderSideWidth::Medium), "thick" => Ok(BorderSideWidth::Thick), diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 53c5d086b33..b5482b0cc2b 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -23,7 +23,7 @@ impl Parse for VerticalAlign { return Ok(GenericVerticalAlign::Length(lop)); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "baseline" => Ok(GenericVerticalAlign::Baseline), "sub" => Ok(GenericVerticalAlign::Sub), "super" => Ok(GenericVerticalAlign::Super), diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index 3ac81d5903c..dd0a6f8c676 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -6,11 +6,11 @@ //! //! [calc]: https://drafts.csswg.org/css-values/#calc-notation -use cssparser::{Parser, Token, BasicParseError}; +use cssparser::{Parser, Token}; use parser::ParserContext; use std::ascii::AsciiExt; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::values::specified::AllowedNumericType; use values::{CSSInteger, CSSFloat}; use values::computed; @@ -170,6 +170,7 @@ impl CalcNode { input: &mut Parser<'i, 't>, expected_unit: CalcUnit ) -> Result> { + let location = input.current_source_location(); // FIXME: remove early returns when lifetimes are non-lexical match (input.next()?, expected_unit) { (&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)), @@ -177,17 +178,17 @@ impl CalcNode { (&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => { return NoCalcLength::parse_dimension(context, value, unit) .map(CalcNode::Length) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => { return Angle::parse_dimension(value, unit, /* from_calc = */ true) .map(CalcNode::Angle) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => { return Time::parse_dimension(value, unit, /* from_calc = */ true) .map(CalcNode::Time) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { @@ -195,7 +196,7 @@ impl CalcNode { } (&Token::ParenthesisBlock, _) => {} (&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {} - (t, _) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()) + (t, _) => return Err(location.new_unexpected_token_error(t.clone())) } input.parse_nested_block(|i| { CalcNode::parse(context, i, expected_unit) @@ -236,7 +237,7 @@ impl CalcNode { CalcNode::Sub(Box::new(root), Box::new(rhs)); root = new_root; } - t => return Err(BasicParseError::UnexpectedToken(t).into()), + t => return Err(input.new_unexpected_token_error(t)), } } _ => { @@ -559,7 +560,7 @@ impl CalcNode { Self::parse(context, input, CalcUnit::Integer)? .to_number() .map(|n| n as CSSInteger) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ` | `. @@ -570,7 +571,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::LengthOrPercentage)? .to_length_or_percentage(clamping_mode) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for percentages. @@ -580,7 +581,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Percentage)? .to_percentage() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -591,7 +592,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Length)? .to_length_or_percentage(clamping_mode) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -601,7 +602,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Number)? .to_number() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -611,7 +612,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Angle)? .to_angle() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for `