Bug 1371393 - Stylo: set location for NestedRuleParser during prelude parsing. r?SimonSapin draft
authorFernando Jimenez Moreno <ferjmoreno@gmail.com>
Wed, 14 Jun 2017 17:04:23 +0200
changeset 594100 26d8c325348c4abe2c564f6f618f4971d108ef3f
parent 593717 b266a8d8fd595b84a7d6218d7b8c6b7af0b5027c
child 633333 97751b53792835add66a22f03dc25373b21ec072
push id63933
push userferjmoreno@gmail.com
push dateWed, 14 Jun 2017 15:14:57 +0000
reviewersSimonSapin
bugs1371393
milestone56.0a1
Bug 1371393 - Stylo: set location for NestedRuleParser during prelude parsing. r?SimonSapin MozReview-Commit-ID: Ay0as4f4BZ7
servo/components/style/stylesheets/rule_parser.rs
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -252,41 +252,45 @@ impl<'a, 'i> AtRuleParser<'i> for TopLev
 
     #[inline]
     fn parse_block<'t>(&mut self, prelude: AtRulePrelude, input: &mut Parser<'i, 't>)
                        -> Result<CssRule, ParseError<'i>> {
         AtRuleParser::parse_block(&mut self.nested(), prelude, input)
     }
 }
 
+pub struct QualifiedRuleParserPrelude {
+    selectors: SelectorList<SelectorImpl>,
+    source_location: SourceLocation,
+}
 
 impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> {
-    type Prelude = SelectorList<SelectorImpl>;
+    type Prelude = QualifiedRuleParserPrelude;
     type QualifiedRule = CssRule;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
     #[inline]
     fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>)
-                         -> Result<SelectorList<SelectorImpl>, ParseError<'i>> {
+                         -> Result<QualifiedRuleParserPrelude, ParseError<'i>> {
         self.state = State::Body;
 
         // "Freeze" the namespace map (no more namespace rules can be parsed
         // after this point), and stick it in the context.
         if self.namespaces.is_some() {
             let namespaces = &*self.namespaces.take().unwrap();
             self.context.namespaces = Some(namespaces);
         }
 
         QualifiedRuleParser::parse_prelude(&mut self.nested(), input)
     }
 
     #[inline]
     fn parse_block<'t>(
         &mut self,
-        prelude: SelectorList<SelectorImpl>,
+        prelude: QualifiedRuleParserPrelude,
         input: &mut Parser<'i, 't>
     ) -> Result<CssRule, ParseError<'i>> {
         QualifiedRuleParser::parse_block(&mut self.nested(), prelude, input)
     }
 }
 
 #[derive(Clone)]  // shallow, relatively cheap .clone
 struct NestedRuleParser<'a, 'b: 'a> {
@@ -477,43 +481,48 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for Ne
                     unreachable!()
                 }
             }
         }
     }
 }
 
 impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
-    type Prelude = SelectorList<SelectorImpl>;
+    type Prelude = QualifiedRuleParserPrelude;
     type QualifiedRule = CssRule;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
     fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>)
-                         -> Result<SelectorList<SelectorImpl>, ParseError<'i>> {
+                         -> Result<QualifiedRuleParserPrelude, ParseError<'i>> {
         let selector_parser = SelectorParser {
             stylesheet_origin: self.stylesheet_origin,
             namespaces: self.context.namespaces.unwrap(),
         };
 
-        SelectorList::parse(&selector_parser, input)
+        let location = get_location_with_offset(input.current_source_location(),
+                                                self.context.line_number_offset);
+        let selectors = SelectorList::parse(&selector_parser, input)?;
+
+        Ok(QualifiedRuleParserPrelude {
+            selectors: selectors,
+            source_location: location,
+        })
     }
 
     fn parse_block<'t>(
         &mut self,
-        prelude: SelectorList<SelectorImpl>,
+        prelude: QualifiedRuleParserPrelude,
         input: &mut Parser<'i, 't>
     ) -> Result<CssRule, ParseError<'i>> {
-        let location = get_location_with_offset(input.current_source_location(),
-                                                self.context.line_number_offset);
         let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Style));
         let declarations = parse_property_declaration_list(&context, input);
         Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
-            selectors: prelude,
+            selectors: prelude.selectors,
             block: Arc::new(self.shared_lock.wrap(declarations)),
-            source_location: location,
+            source_location: prelude.source_location,
         }))))
     }
 }
 
 /// Calculates the location of a rule's source given an offset.
 fn get_location_with_offset(
     location: SourceLocation,
     offset: u64