diff options
author | Josh Matthews <josh@joshmatthews.net> | 2017-08-23 17:50:13 -0700 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2017-08-24 10:41:06 -0700 |
commit | 1297c0ff51f1f5ab39221d6489574bcd7a85663b (patch) | |
tree | 33dba5dec67902da55351107336968a8145b3e0e /components/style | |
parent | 2e775abfa4563fc5db467c5c79f9d2507f6bb2e7 (diff) | |
download | servo-1297c0ff51f1f5ab39221d6489574bcd7a85663b.tar.gz servo-1297c0ff51f1f5ab39221d6489574bcd7a85663b.zip |
Devirtualize CSS error reporting.
Diffstat (limited to 'components/style')
-rw-r--r-- | components/style/counter_style/mod.rs | 17 | ||||
-rw-r--r-- | components/style/encoding_support.rs | 40 | ||||
-rw-r--r-- | components/style/font_face.rs | 15 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 11 | ||||
-rw-r--r-- | components/style/parser.rs | 24 | ||||
-rw-r--r-- | components/style/properties/declaration_block.rs | 51 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 3 | ||||
-rw-r--r-- | components/style/stylesheets/font_feature_values_rule.rs | 27 | ||||
-rw-r--r-- | components/style/stylesheets/keyframes_rule.rs | 26 | ||||
-rw-r--r-- | components/style/stylesheets/mod.rs | 4 | ||||
-rw-r--r-- | components/style/stylesheets/rule_parser.rs | 43 | ||||
-rw-r--r-- | components/style/stylesheets/stylesheet.rs | 52 | ||||
-rw-r--r-- | components/style/stylesheets/viewport_rule.rs | 16 |
13 files changed, 191 insertions, 138 deletions
diff --git a/components/style/counter_style/mod.rs b/components/style/counter_style/mod.rs index df405e9f262..26895688971 100644 --- a/components/style/counter_style/mod.rs +++ b/components/style/counter_style/mod.rs @@ -9,10 +9,10 @@ use Atom; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr}; -use error_reporting::ContextualParseError; +use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc; -use parser::{ParserContext, Parse}; +use parser::{ParserContext, ParserErrorContext, Parse}; use selectors::parser::SelectorParseError; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::ascii::AsciiExt; @@ -50,8 +50,13 @@ pub fn parse_counter_style_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Cu } /// Parse the body (inside `{}`) of an @counter-style rule -pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<CounterStyleRuleData, ParseError<'i>> { +pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent, + context: &ParserContext, + error_context: &ParserErrorContext<R>, + input: &mut Parser<'i, 't>) + -> Result<CounterStyleRuleData, ParseError<'i>> + where R: ParseErrorReporter +{ let start = input.current_source_location(); let mut rule = CounterStyleRuleData::empty(name); { @@ -63,7 +68,7 @@ pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserConte while let Some(declaration) = iter.next() { if let Err(err) = declaration { let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error); - context.log_css_error(err.location, error) + context.log_css_error(error_context, err.location, error) } } } @@ -95,7 +100,7 @@ pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserConte _ => None }; if let Some(error) = error { - context.log_css_error(start, error); + context.log_css_error(error_context, start, error); Err(StyleParseError::UnspecifiedError.into()) } else { Ok(rule) diff --git a/components/style/encoding_support.rs b/components/style/encoding_support.rs index 6560342e942..a354938c3a7 100644 --- a/components/style/encoding_support.rs +++ b/components/style/encoding_support.rs @@ -49,17 +49,19 @@ impl Stylesheet { /// /// Takes care of decoding the network bytes and forwards the resulting /// string to `Stylesheet::from_str`. - pub fn from_bytes(bytes: &[u8], - url_data: UrlExtraData, - protocol_encoding_label: Option<&str>, - environment_encoding: Option<EncodingRef>, - origin: Origin, - media: MediaList, - shared_lock: SharedRwLock, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, - quirks_mode: QuirksMode) - -> Stylesheet { + pub fn from_bytes<R>(bytes: &[u8], + url_data: UrlExtraData, + protocol_encoding_label: Option<&str>, + environment_encoding: Option<EncodingRef>, + origin: Origin, + media: MediaList, + shared_lock: SharedRwLock, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &R, + quirks_mode: QuirksMode) + -> Stylesheet + where R: ParseErrorReporter + { let (string, _) = decode_stylesheet_bytes( bytes, protocol_encoding_label, environment_encoding); Stylesheet::from_str(&string, @@ -75,13 +77,15 @@ impl Stylesheet { /// Updates an empty stylesheet with a set of bytes that reached over the /// network. - pub fn update_from_bytes(existing: &Stylesheet, - bytes: &[u8], - protocol_encoding_label: Option<&str>, - environment_encoding: Option<EncodingRef>, - url_data: UrlExtraData, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter) { + pub fn update_from_bytes<R>(existing: &Stylesheet, + bytes: &[u8], + protocol_encoding_label: Option<&str>, + environment_encoding: Option<EncodingRef>, + url_data: UrlExtraData, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &R) + where R: ParseErrorReporter + { let (string, _) = decode_stylesheet_bytes( bytes, protocol_encoding_label, environment_encoding); Self::update_from_str(existing, diff --git a/components/style/font_face.rs b/components/style/font_face.rs index b2d130cc510..48658e9c6fa 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -13,10 +13,10 @@ use computed_values::{font_feature_settings, font_stretch, font_style, font_weig use computed_values::font_family::FamilyName; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{SourceLocation, CowRcStr}; -use error_reporting::ContextualParseError; +use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors; #[cfg(feature = "gecko")] use cssparser::UnicodeRange; -use parser::{ParserContext, Parse}; +use parser::{ParserContext, ParserErrorContext, Parse}; #[cfg(feature = "gecko")] use properties::longhands::font_language_override; use selectors::parser::SelectorParseError; @@ -108,8 +108,13 @@ impl Parse for FontWeight { /// Parse the block inside a `@font-face` rule. /// /// Note that the prelude parsing code lives in the `stylesheets` module. -pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser, location: SourceLocation) - -> FontFaceRuleData { +pub fn parse_font_face_block<R>(context: &ParserContext, + error_context: &ParserErrorContext<R>, + input: &mut Parser, + location: SourceLocation) + -> FontFaceRuleData + where R: ParseErrorReporter +{ let mut rule = FontFaceRuleData::empty(location); { let parser = FontFaceRuleParser { @@ -120,7 +125,7 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser, locati while let Some(declaration) = iter.next() { if let Err(err) = declaration { let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error); - context.log_css_error(err.location, error) + context.log_css_error(error_context, err.location, error) } } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 4b7e5993334..7261d02afc7 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -467,10 +467,13 @@ impl<'le> fmt::Debug for GeckoElement<'le> { impl<'le> GeckoElement<'le> { /// Parse the style attribute of an element. - pub fn parse_style_attribute(value: &str, - url_data: &UrlExtraData, - quirks_mode: QuirksMode, - reporter: &ParseErrorReporter) -> PropertyDeclarationBlock { + pub fn parse_style_attribute<R>(value: &str, + url_data: &UrlExtraData, + quirks_mode: QuirksMode, + reporter: &R) + -> PropertyDeclarationBlock + where R: ParseErrorReporter + { parse_style_attribute(value, url_data, reporter, quirks_mode) } diff --git a/components/style/parser.rs b/components/style/parser.rs index 4d38549ee69..c4167b6865a 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -38,6 +38,12 @@ pub fn assert_parsing_mode_match() { } } +/// The context required to report a parse error. +pub struct ParserErrorContext<'a, R: 'a> { + /// An error reporter to report syntax errors. + pub error_reporter: &'a R, +} + /// The data that the parser needs from outside in order to parse a stylesheet. pub struct ParserContext<'a> { /// The `Origin` of the stylesheet, whether it's a user, author or @@ -45,8 +51,6 @@ pub struct ParserContext<'a> { pub stylesheet_origin: Origin, /// The extra data we need for resolving url values. pub url_data: &'a UrlExtraData, - /// An error reporter to report syntax errors. - pub error_reporter: &'a ParseErrorReporter, /// The current rule type, if any. pub rule_type: Option<CssRuleType>, /// Line number offsets for inline stylesheets @@ -64,7 +68,6 @@ impl<'a> ParserContext<'a> { pub fn new( stylesheet_origin: Origin, url_data: &'a UrlExtraData, - error_reporter: &'a ParseErrorReporter, rule_type: Option<CssRuleType>, parsing_mode: ParsingMode, quirks_mode: QuirksMode, @@ -72,7 +75,6 @@ impl<'a> ParserContext<'a> { ParserContext { stylesheet_origin: stylesheet_origin, url_data: url_data, - error_reporter: error_reporter, rule_type: rule_type, line_number_offset: 0u64, parsing_mode: parsing_mode, @@ -84,7 +86,6 @@ impl<'a> ParserContext<'a> { /// Create a parser context for on-the-fly parsing in CSSOM pub fn new_for_cssom( url_data: &'a UrlExtraData, - error_reporter: &'a ParseErrorReporter, rule_type: Option<CssRuleType>, parsing_mode: ParsingMode, quirks_mode: QuirksMode @@ -92,7 +93,6 @@ impl<'a> ParserContext<'a> { Self::new( Origin::Author, url_data, - error_reporter, rule_type, parsing_mode, quirks_mode, @@ -108,7 +108,6 @@ impl<'a> ParserContext<'a> { ParserContext { stylesheet_origin: context.stylesheet_origin, url_data: context.url_data, - error_reporter: context.error_reporter, rule_type: Some(rule_type), line_number_offset: context.line_number_offset, parsing_mode: context.parsing_mode, @@ -121,7 +120,6 @@ impl<'a> ParserContext<'a> { pub fn new_with_line_number_offset( stylesheet_origin: Origin, url_data: &'a UrlExtraData, - error_reporter: &'a ParseErrorReporter, line_number_offset: u64, parsing_mode: ParsingMode, quirks_mode: QuirksMode, @@ -129,7 +127,6 @@ impl<'a> ParserContext<'a> { ParserContext { stylesheet_origin: stylesheet_origin, url_data: url_data, - error_reporter: error_reporter, rule_type: None, line_number_offset: line_number_offset, parsing_mode: parsing_mode, @@ -144,12 +141,17 @@ impl<'a> ParserContext<'a> { } /// Record a CSS parse error with this context’s error reporting. - pub fn log_css_error(&self, location: SourceLocation, error: ContextualParseError) { + pub fn log_css_error<R>(&self, + context: &ParserErrorContext<R>, + location: SourceLocation, + error: ContextualParseError) + where R: ParseErrorReporter + { let location = SourceLocation { line: location.line + self.line_number_offset as u32, column: location.column, }; - self.error_reporter.report_error(self.url_data, location, error) + context.error_reporter.report_error(self.url_data, location, error) } } diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 07bc5eeab1d..1136f514857 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -10,7 +10,7 @@ use context::QuirksMode; use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr}; use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError}; use error_reporting::{ParseErrorReporter, ContextualParseError}; -use parser::ParserContext; +use parser::{ParserContext, ParserErrorContext}; use properties::animated_properties::AnimationValue; use selectors::parser::SelectorParseError; use shared_lock::Locked; @@ -896,36 +896,39 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W, /// A helper to parse the style attribute of an element, in order for this to be /// shared between Servo and Gecko. -pub fn parse_style_attribute(input: &str, - url_data: &UrlExtraData, - error_reporter: &ParseErrorReporter, - quirks_mode: QuirksMode) - -> PropertyDeclarationBlock { +pub fn parse_style_attribute<R>(input: &str, + url_data: &UrlExtraData, + error_reporter: &R, + quirks_mode: QuirksMode) + -> PropertyDeclarationBlock + where R: ParseErrorReporter +{ let context = ParserContext::new(Origin::Author, url_data, - error_reporter, Some(CssRuleType::Style), PARSING_MODE_DEFAULT, quirks_mode); + let error_context = ParserErrorContext { error_reporter: error_reporter }; let mut input = ParserInput::new(input); - parse_property_declaration_list(&context, &mut Parser::new(&mut input)) + parse_property_declaration_list(&context, &error_context, &mut Parser::new(&mut input)) } /// Parse a given property declaration. Can result in multiple /// `PropertyDeclaration`s when expanding a shorthand, for example. /// /// This does not attempt to parse !important at all. -pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaration, - id: PropertyId, - input: &str, - url_data: &UrlExtraData, - error_reporter: &ParseErrorReporter, - parsing_mode: ParsingMode, - quirks_mode: QuirksMode) - -> Result<(), ()> { +pub fn parse_one_declaration_into<R>(declarations: &mut SourcePropertyDeclaration, + id: PropertyId, + input: &str, + url_data: &UrlExtraData, + error_reporter: &R, + parsing_mode: ParsingMode, + quirks_mode: QuirksMode) + -> Result<(), ()> + where R: ParseErrorReporter +{ let context = ParserContext::new(Origin::Author, url_data, - error_reporter, Some(CssRuleType::Style), parsing_mode, quirks_mode); @@ -939,7 +942,8 @@ pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaration, }).map_err(|err| { let error = ContextualParseError::UnsupportedPropertyDeclaration( parser.slice_from(start_position), err); - context.log_css_error(start_location, error); + let error_context = ParserErrorContext { error_reporter: error_reporter }; + context.log_css_error(&error_context, start_location, error); }) } @@ -997,9 +1001,12 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { /// Parse a list of property declarations and return a property declaration /// block. -pub fn parse_property_declaration_list(context: &ParserContext, - input: &mut Parser) - -> PropertyDeclarationBlock { +pub fn parse_property_declaration_list<R>(context: &ParserContext, + error_context: &ParserErrorContext<R>, + input: &mut Parser) + -> PropertyDeclarationBlock + where R: ParseErrorReporter +{ let mut declarations = SourcePropertyDeclaration::new(); let mut block = PropertyDeclarationBlock::new(); let parser = PropertyDeclarationParser { @@ -1024,7 +1031,7 @@ pub fn parse_property_declaration_list(context: &ParserContext, } let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error); - context.log_css_error(err.location, error); + context.log_css_error(error_context, err.location, error); } } } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index f64117e1bfc..b7986e2cac4 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -23,7 +23,6 @@ use cssparser::ParserInput; #[cfg(feature = "servo")] use euclid::SideOffsets2D; use computed_values; use context::QuirksMode; -use error_reporting::NullReporter; use font_metrics::FontMetricsProvider; #[cfg(feature = "gecko")] use gecko_bindings::bindings; #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID}; @@ -828,10 +827,8 @@ impl UnparsedValue { .ok() .and_then(|css| { // As of this writing, only the base URL is used for property values: - let reporter = NullReporter; let context = ParserContext::new(Origin::Author, &self.url_data, - &reporter, None, PARSING_MODE_DEFAULT, quirks_mode); diff --git a/components/style/stylesheets/font_feature_values_rule.rs b/components/style/stylesheets/font_feature_values_rule.rs index df30013b35b..3d765616367 100644 --- a/components/style/stylesheets/font_feature_values_rule.rs +++ b/components/style/stylesheets/font_feature_values_rule.rs @@ -10,8 +10,8 @@ use Atom; use computed_values::font_family::FamilyName; use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier}; -use error_reporting::ContextualParseError; -use parser::{ParserContext, Parse}; +use error_reporting::{ContextualParseError, ParseErrorReporter}; +use parser::{ParserContext, ParserErrorContext, Parse}; use selectors::parser::SelectorParseError; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; @@ -210,20 +210,26 @@ macro_rules! font_feature_values_blocks { } /// Parses a `FontFeatureValuesRule`. - pub fn parse(context: &ParserContext, input: &mut Parser, - family_names: Vec<FamilyName>, location: SourceLocation) - -> FontFeatureValuesRule { + pub fn parse<R>(context: &ParserContext, + error_context: &ParserErrorContext<R>, + input: &mut Parser, + family_names: Vec<FamilyName>, + location: SourceLocation) + -> FontFeatureValuesRule + where R: ParseErrorReporter + { let mut rule = FontFeatureValuesRule::new(family_names, location); { let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser { context: context, + error_context: error_context, 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(err.location, error); + context.log_css_error(error_context, err.location, error); } } } @@ -293,19 +299,20 @@ macro_rules! font_feature_values_blocks { /// } /// <feature-type> = @stylistic | @historical-forms | @styleset | /// @character-variant | @swash | @ornaments | @annotation - struct FontFeatureValuesRuleParser<'a> { + struct FontFeatureValuesRuleParser<'a, R: 'a> { context: &'a ParserContext<'a>, + error_context: &'a ParserErrorContext<'a, R>, rule: &'a mut FontFeatureValuesRule, } /// Default methods reject all qualified rules. - impl<'a, 'i> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a> { + impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type Prelude = (); type QualifiedRule = (); type Error = SelectorParseError<'i, StyleParseError<'i>>; } - impl<'a, 'i> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a> { + impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type Prelude = BlockType; type AtRule = (); type Error = SelectorParseError<'i, StyleParseError<'i>>; @@ -341,7 +348,7 @@ macro_rules! font_feature_values_blocks { if let Err(err) = declaration { let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration( err.slice, err.error); - self.context.log_css_error(err.location, error); + self.context.log_css_error(self.error_context, err.location, error); } } }, diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs index 7fc292a339e..17828b334d3 100644 --- a/components/style/stylesheets/keyframes_rule.rs +++ b/components/style/stylesheets/keyframes_rule.rs @@ -6,8 +6,8 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CowRcStr}; use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation}; -use error_reporting::{NullReporter, ContextualParseError}; -use parser::ParserContext; +use error_reporting::{NullReporter, ContextualParseError, ParseErrorReporter}; +use parser::{ParserContext, ParserErrorContext}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, PropertyParserContext}; use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration}; use properties::LonghandIdSet; @@ -218,11 +218,11 @@ impl Keyframe { let mut context = ParserContext::new( parent_stylesheet_contents.origin, &url_data, - &error_reporter, Some(CssRuleType::Keyframe), PARSING_MODE_DEFAULT, parent_stylesheet_contents.quirks_mode ); + let error_context = ParserErrorContext { error_reporter: &error_reporter }; context.namespaces = Some(&*namespaces); let mut input = ParserInput::new(css); let mut input = Parser::new(&mut input); @@ -230,6 +230,7 @@ impl Keyframe { let mut declarations = SourcePropertyDeclaration::new(); let mut rule_parser = KeyframeListParser { context: &context, + error_context: &error_context, shared_lock: &lock, declarations: &mut declarations, }; @@ -447,37 +448,42 @@ impl KeyframesAnimation { /// 40%, 60%, 100% { /// width: 100%; /// } -struct KeyframeListParser<'a> { +struct KeyframeListParser<'a, R: 'a> { context: &'a ParserContext<'a>, + error_context: &'a ParserErrorContext<'a, R>, shared_lock: &'a SharedRwLock, declarations: &'a mut SourcePropertyDeclaration, } /// Parses a keyframe list from CSS input. -pub fn parse_keyframe_list( +pub fn parse_keyframe_list<R>( context: &ParserContext, + error_context: &ParserErrorContext<R>, input: &mut Parser, shared_lock: &SharedRwLock -) -> Vec<Arc<Locked<Keyframe>>> { +) -> Vec<Arc<Locked<Keyframe>>> + where R: ParseErrorReporter +{ debug_assert!(context.namespaces.is_some(), "Parsing a keyframe list from a context without namespaces?"); let mut declarations = SourcePropertyDeclaration::new(); RuleListParser::new_for_nested_rule(input, KeyframeListParser { context: context, + error_context: error_context, shared_lock: shared_lock, declarations: &mut declarations, }).filter_map(Result::ok).collect() } enum Void {} -impl<'a, 'i> AtRuleParser<'i> for KeyframeListParser<'a> { +impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> { type Prelude = Void; type AtRule = Arc<Locked<Keyframe>>; type Error = SelectorParseError<'i, StyleParseError<'i>>; } -impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { +impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> { type Prelude = KeyframeSelector; type QualifiedRule = Arc<Locked<Keyframe>>; type Error = SelectorParseError<'i, StyleParseError<'i>>; @@ -489,7 +495,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { Ok(sel) => Ok(sel), Err(e) => { let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone()); - self.context.log_css_error(start_location, error); + self.context.log_css_error(self.error_context, start_location, error); Err(e) } } @@ -518,7 +524,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { Err(err) => { iter.parser.declarations.clear(); let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error); - context.log_css_error(err.location, error); + context.log_css_error(self.error_context, err.location, error); } } // `parse_important` is not called here, `!important` is not allowed in keyframe blocks. diff --git a/components/style/stylesheets/mod.rs b/components/style/stylesheets/mod.rs index 1ec7cbbfb06..25a91b4f7a9 100644 --- a/components/style/stylesheets/mod.rs +++ b/components/style/stylesheets/mod.rs @@ -26,7 +26,7 @@ pub mod viewport_rule; use cssparser::{parse_one_rule, Parser, ParserInput}; use error_reporting::NullReporter; -use parser::ParserContext; +use parser::{ParserContext, ParserErrorContext}; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; @@ -230,7 +230,6 @@ impl CssRule { let context = ParserContext::new( parent_stylesheet_contents.origin, &url_data, - &error_reporter, None, PARSING_MODE_DEFAULT, parent_stylesheet_contents.quirks_mode, @@ -246,6 +245,7 @@ impl CssRule { let mut rule_parser = TopLevelRuleParser { stylesheet_origin: parent_stylesheet_contents.origin, context: context, + error_context: ParserErrorContext { error_reporter: &error_reporter }, shared_lock: &shared_lock, loader: loader, state: state, diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs index 4f9fe566c90..65bcd7cd149 100644 --- a/components/style/stylesheets/rule_parser.rs +++ b/components/style/stylesheets/rule_parser.rs @@ -9,10 +9,10 @@ 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 error_reporting::ContextualParseError; +use error_reporting::{ContextualParseError, ParseErrorReporter}; use font_face::parse_font_face_block; use media_queries::{parse_media_query_list, MediaList}; -use parser::{Parse, ParserContext}; +use parser::{Parse, ParserContext, ParserErrorContext}; use properties::parse_property_declaration_list; use selector_parser::{SelectorImpl, SelectorParser}; use selectors::SelectorList; @@ -35,7 +35,7 @@ use values::KeyframesName; use values::specified::url::SpecifiedUrl; /// The parser for the top-level rules in a stylesheet. -pub struct TopLevelRuleParser<'a> { +pub struct TopLevelRuleParser<'a, R: 'a> { /// The origin of the stylesheet we're parsing. pub stylesheet_origin: Origin, /// A reference to the lock we need to use to create rules. @@ -47,6 +47,8 @@ pub struct TopLevelRuleParser<'a> { /// This won't contain any namespaces, and only nested parsers created with /// `ParserContext::new_with_rule_type` will. pub context: ParserContext<'a>, + /// The context required for reporting parse errors. + pub error_context: ParserErrorContext<'a, R>, /// The current state of the parser. pub state: State, /// Whether we have tried to parse was invalid due to being in the wrong @@ -59,12 +61,13 @@ pub struct TopLevelRuleParser<'a> { pub namespaces: &'a mut Namespaces, } -impl<'b> TopLevelRuleParser<'b> { - fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> { +impl<'b, R> TopLevelRuleParser<'b, R> { + fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b, R> { NestedRuleParser { stylesheet_origin: self.stylesheet_origin, shared_lock: self.shared_lock, context: &self.context, + error_context: &self.error_context, namespaces: &self.namespaces, } } @@ -147,7 +150,7 @@ fn register_namespace(_: &Namespace) -> Result<(), ()> { Ok(()) // servo doesn't use namespace ids } -impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { +impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> { type Prelude = AtRulePrelude; type AtRule = CssRule; type Error = SelectorParseError<'i, StyleParseError<'i>>; @@ -256,7 +259,7 @@ pub struct QualifiedRuleParserPrelude { source_location: SourceLocation, } -impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> { +impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> { type Prelude = QualifiedRuleParserPrelude; type QualifiedRule = CssRule; type Error = SelectorParseError<'i, StyleParseError<'i>>; @@ -281,14 +284,15 @@ impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> { } #[derive(Clone)] // shallow, relatively cheap .clone -struct NestedRuleParser<'a, 'b: 'a> { +struct NestedRuleParser<'a, 'b: 'a, R: 'b> { stylesheet_origin: Origin, shared_lock: &'a SharedRwLock, context: &'a ParserContext<'b>, + error_context: &'a ParserErrorContext<'b, R>, namespaces: &'a Namespaces, } -impl<'a, 'b> NestedRuleParser<'a, 'b> { +impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> { fn parse_nested_rules( &mut self, input: &mut Parser, @@ -301,6 +305,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> { stylesheet_origin: self.stylesheet_origin, shared_lock: self.shared_lock, context: &context, + error_context: &self.error_context, namespaces: self.namespaces, }; @@ -311,7 +316,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> { Ok(rule) => rules.push(rule), Err(err) => { let error = ContextualParseError::UnsupportedRule(err.slice, err.error); - self.context.log_css_error(err.location, error); + self.context.log_css_error(self.error_context, err.location, error); } } } @@ -319,7 +324,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> { } } -impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { +impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a, 'b, R> { type Prelude = AtRulePrelude; type AtRule = CssRule; type Error = SelectorParseError<'i, StyleParseError<'i>>; @@ -428,7 +433,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { ); Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap( - parse_font_face_block(&context, input, location).into())))) + parse_font_face_block(&context, self.error_context, input, location).into())))) } AtRulePrelude::FontFeatureValues(family_names, location) => { let context = @@ -438,7 +443,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { self.namespaces, ); Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap( - FontFeatureValuesRule::parse(&context, input, family_names, location))))) + FontFeatureValuesRule::parse(&context, self.error_context, input, family_names, location))))) } AtRulePrelude::CounterStyle(name) => { let context = @@ -448,7 +453,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { self.namespaces, ); Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap( - parse_counter_style_body(name, &context, input)?.into())))) + parse_counter_style_body(name, &context, self.error_context, input)?.into())))) } AtRulePrelude::Media(media_queries, location) => { Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule { @@ -480,7 +485,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { self.namespaces, ); Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap( - ViewportRule::parse(&context, input)?)))) + ViewportRule::parse(&context, self.error_context, input)?)))) } AtRulePrelude::Keyframes(name, prefix, location) => { let context = @@ -492,7 +497,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule { name: name, - keyframes: parse_keyframe_list(&context, input, self.shared_lock), + keyframes: parse_keyframe_list(&context, self.error_context, input, self.shared_lock), vendor_prefix: prefix, source_location: location, })))) @@ -504,7 +509,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { CssRuleType::Page, self.namespaces, ); - let declarations = parse_property_declaration_list(&context, input); + let declarations = parse_property_declaration_list(&context, self.error_context, input); Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule { block: Arc::new(self.shared_lock.wrap(declarations)), source_location: location, @@ -525,7 +530,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { } } -impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> { +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>>; @@ -561,7 +566,7 @@ impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> { CssRuleType::Style, self.namespaces, ); - let declarations = parse_property_declaration_list(&context, input); + let declarations = parse_property_declaration_list(&context, self.error_context, input); Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule { selectors: prelude.selectors, block: Arc::new(self.shared_lock.wrap(declarations)), diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs index 9dc8446f6b6..b71863dab6b 100644 --- a/components/style/stylesheets/stylesheet.rs +++ b/components/style/stylesheets/stylesheet.rs @@ -10,7 +10,7 @@ use fnv::FnvHashMap; use invalidation::media_queries::{MediaListKey, ToMediaListKey}; use media_queries::{MediaList, Device}; use parking_lot::RwLock; -use parser::ParserContext; +use parser::{ParserContext, ParserErrorContext}; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; use std::mem; @@ -67,13 +67,13 @@ pub struct StylesheetContents { impl StylesheetContents { /// Parse a given CSS string, with a given url-data, origin, and /// quirks mode. - pub fn from_str( + pub fn from_str<R: ParseErrorReporter>( css: &str, url_data: UrlExtraData, origin: Origin, shared_lock: &SharedRwLock, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, + error_reporter: &R, quirks_mode: QuirksMode, line_number_offset: u64 ) -> Self { @@ -313,12 +313,14 @@ impl StylesheetInDocument for DocumentStyleSheet { impl Stylesheet { /// Updates an empty stylesheet from a given string of text. - pub fn update_from_str(existing: &Stylesheet, - css: &str, - url_data: UrlExtraData, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, - line_number_offset: u64) { + pub fn update_from_str<R>(existing: &Stylesheet, + css: &str, + url_data: UrlExtraData, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &R, + line_number_offset: u64) + where R: ParseErrorReporter + { let namespaces = RwLock::new(Namespaces::default()); let (rules, dirty_on_viewport_size_change, source_map_url) = Stylesheet::parse_rules( @@ -347,14 +349,14 @@ impl Stylesheet { *existing.contents.source_map_url.write() = source_map_url; } - fn parse_rules( + fn parse_rules<R: ParseErrorReporter>( css: &str, url_data: &UrlExtraData, origin: Origin, namespaces: &mut Namespaces, shared_lock: &SharedRwLock, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, + error_reporter: &R, quirks_mode: QuirksMode, line_number_offset: u64 ) -> (Vec<CssRule>, bool, Option<String>) { @@ -366,17 +368,18 @@ impl Stylesheet { ParserContext::new_with_line_number_offset( origin, url_data, - error_reporter, line_number_offset, PARSING_MODE_DEFAULT, quirks_mode ); + let error_context = ParserErrorContext { error_reporter }; let rule_parser = TopLevelRuleParser { stylesheet_origin: origin, shared_lock: shared_lock, loader: stylesheet_loader, context: context, + error_context: error_context, state: State::Start, had_hierarchy_error: false, namespaces: namespaces, @@ -393,7 +396,8 @@ impl Stylesheet { Ok(rule) => rules.push(rule), Err(err) => { let error = ContextualParseError::InvalidRule(err.slice, err.error); - iter.parser.context.log_css_error(err.location, error); + iter.parser.context.log_css_error(&iter.parser.error_context, + err.location, error); } } } @@ -408,16 +412,18 @@ impl Stylesheet { /// /// Effectively creates a new stylesheet and forwards the hard work to /// `Stylesheet::update_from_str`. - pub fn from_str(css: &str, - url_data: UrlExtraData, - origin: Origin, - media: Arc<Locked<MediaList>>, - shared_lock: SharedRwLock, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, - quirks_mode: QuirksMode, - line_number_offset: u64) - -> Stylesheet { + pub fn from_str<R: ParseErrorReporter>( + css: &str, + url_data: UrlExtraData, + origin: Origin, + media: Arc<Locked<MediaList>>, + shared_lock: SharedRwLock, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &R, + quirks_mode: QuirksMode, + line_number_offset: u64) + -> Stylesheet + { let contents = StylesheetContents::from_str( css, url_data, diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index a98f5807fa6..1e58553e676 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -11,11 +11,11 @@ use app_units::Au; use context::QuirksMode; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important}; use cssparser::{CowRcStr, ToCss as ParserToCss}; -use error_reporting::ContextualParseError; +use error_reporting::{ContextualParseError, ParseErrorReporter}; use euclid::TypedSize2D; use font_metrics::get_metrics_provider_for_product; use media_queries::Device; -use parser::{Parse, ParserContext}; +use parser::{ParserContext, ParserErrorContext}; use properties::StyleBuilder; use selectors::parser::SelectorParseError; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; @@ -346,8 +346,14 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool { WHITESPACE.contains(c) || SEPARATOR.contains(c) || *c == '=' } -impl Parse for ViewportRule { - fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { +impl ViewportRule { + /// Parse a single @viewport rule. + pub fn parse<'i, 't, R>(context: &ParserContext, + error_context: &ParserErrorContext<R>, + input: &mut Parser<'i, 't>) + -> Result<Self, ParseError<'i>> + where R: ParseErrorReporter + { let parser = ViewportRuleParser { context: context }; let mut cascade = Cascade::new(); @@ -361,7 +367,7 @@ impl Parse for ViewportRule { } Err(err) => { let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error); - context.log_css_error(err.location, error); + context.log_css_error(error_context, err.location, error); } } } |