Bug 591303 - Part 3: Set line and column number for all rules in nsCSSParser. r=bz
authorGabriel Luong <gabriel.luong@gmail.com>
Mon, 14 Jul 2014 15:57:54 -0700
changeset 214745 8acc3d0aa7108642b0d1230072acc68f8221c673
parent 214744 785257a95e363df9238b4ffc7fdc78eabe1b2369
child 214746 6b8e30b71a4ec220b8678fd61bfd8467b2d61eb4
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs591303
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 591303 - Part 3: Set line and column number for all rules in nsCSSParser. r=bz
content/svg/content/src/nsSVGElement.cpp
layout/style/GroupRule.h
layout/style/ImportRule.h
layout/style/NameSpaceRule.h
layout/style/Rule.h
layout/style/StyleAnimationValue.cpp
layout/style/StyleRule.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsDOMCSSAttrDeclaration.cpp
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1208,17 +1208,17 @@ MappedAttrParser::ParseMappedAttrValue(n
 
 already_AddRefed<css::StyleRule>
 MappedAttrParser::CreateStyleRule()
 {
   if (!mDecl) {
     return nullptr; // No mapped attributes were parsed
   }
 
-  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, mDecl);
+  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, mDecl, 0, 0);
   mDecl = nullptr; // We no longer own the declaration -- drop our pointer to it
   return rule.forget();
 }
 
 } // anonymous namespace
 
 //----------------------------------------------------------------------
 // Implementation Helpers:
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -29,17 +29,17 @@ namespace css {
 
 class GroupRuleRuleList;
 
 // inherits from Rule so it can be shared between
 // MediaRule and DocumentRule
 class GroupRule : public Rule
 {
 protected:
-  GroupRule();
+  GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
   GroupRule(const GroupRule& aCopy);
   virtual ~GroupRule();
 public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS(GroupRule)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // implement part of nsIStyleRule and Rule
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -22,17 +22,18 @@ namespace mozilla {
 class CSSStyleSheet;
 
 namespace css {
 
 class ImportRule MOZ_FINAL : public Rule,
                              public nsIDOMCSSImportRule
 {
 public:
-  ImportRule(nsMediaList* aMedia, const nsString& aURLSpec);
+  ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
+             uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   ImportRule(const ImportRule& aCopy);
   ~ImportRule();
 public:
   NS_DECL_ISUPPORTS
 
   DECL_STYLE_RULE_INHERIT
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -23,17 +23,18 @@ class nsIAtom;
 
 namespace mozilla {
 namespace css {
 
 class NameSpaceRule MOZ_FINAL : public Rule,
                                 public nsIDOMCSSRule
 {
 public:
-  NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec);
+  NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
+                uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   NameSpaceRule(const NameSpaceRule& aCopy);
   ~NameSpaceRule();
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
   NS_DECL_ISUPPORTS
--- a/layout/style/Rule.h
+++ b/layout/style/Rule.h
@@ -28,17 +28,17 @@ virtual void MapRuleInfoInto(nsRuleData*
 
 #define DECL_STYLE_RULE_INHERIT                   \
   DECL_STYLE_RULE_INHERIT_NO_DOMRULE              \
   virtual nsIDOMCSSRule* GetDOMRule();            \
   virtual nsIDOMCSSRule* GetExistingDOMRule();
 
 class Rule : public nsIStyleRule {
 protected:
-  Rule(uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0)
+  Rule(uint32_t aLineNumber, uint32_t aColumnNumber)
     : mSheet(0),
       mParentRule(nullptr),
       mLineNumber(aLineNumber),
       mColumnNumber(aColumnNumber),
       mWasMatched(false)
   {
   }
 
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2457,17 +2457,19 @@ BuildStyleRule(nsCSSProperty aProperty,
                                      declaration, &changed, false,
                                      aUseSVGMode)) ||
       // check whether property parsed without CSS parsing errors
       !declaration->HasNonImportantValueFor(propertyToCheck)) {
     NS_WARNING("failure in BuildStyleRule");
     return nullptr;
   }
 
-  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration.forget());
+  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr,
+                                                     declaration.forget(),
+                                                     0, 0);
   return rule.forget();
 }
 
 inline
 already_AddRefed<nsStyleContext>
 LookupStyleContext(dom::Element* aElement)
 {
   nsIDocument* doc = aElement->GetCurrentDoc();
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -298,17 +298,17 @@ protected:
   friend class StyleRule;
 };
 
 class StyleRule MOZ_FINAL : public Rule
 {
  public:
   StyleRule(nsCSSSelectorList* aSelector,
             Declaration *aDeclaration,
-            uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0);
+            uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   StyleRule(const StyleRule& aCopy);
   // for |DeclarationChanged|
   StyleRule(StyleRule& aCopy,
             Declaration *aDeclaration);
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID)
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -459,25 +459,28 @@ protected:
                          // expression" as two.
                          eMediaQuerySingleCondition };
   bool ParseMediaQuery(eMediaQueryType aMode, nsMediaQuery **aQuery,
                        bool *aHitStop);
   bool ParseMediaQueryExpression(nsMediaQuery* aQuery);
   void ProcessImport(const nsString& aURLSpec,
                      nsMediaList* aMedia,
                      RuleAppendFunc aAppendFunc,
-                     void* aProcessData);
+                     void* aProcessData,
+                     uint32_t aLineNumber,
+                     uint32_t aColumnNumber);
   bool ParseGroupRule(css::GroupRule* aRule, RuleAppendFunc aAppendFunc,
                       void* aProcessData);
   bool ParseMediaRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseNameSpaceRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   void ProcessNameSpace(const nsString& aPrefix,
                         const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
-                        void* aProcessData);
+                        void* aProcessData,
+                        uint32_t aLineNumber, uint32_t aColumnNumber);
 
   bool ParseFontFaceRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
                                   void* aProcessData);
   bool ParseFontFeatureValueSet(nsCSSFontFeatureValuesRule *aRule);
   bool ParseFontDescriptor(nsCSSFontFaceRule* aRule);
   bool ParseFontDescriptorValue(nsCSSFontDesc aDescID,
                                 nsCSSValue& aValue);
@@ -1324,17 +1327,17 @@ CSSParserImpl::ParseStyleAttribute(const
 
   mSection = eCSSSection_General;
 
   uint32_t parseFlags = eParseDeclaration_AllowImportant;
 
   css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
   if (declaration) {
     // Create a style rule for the declaration
-    NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration));
+    NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration, 0, 0));
   } else {
     *aResult = nullptr;
   }
 
   ReleaseScanner();
 
   // XXX check for low level errors
   return NS_OK;
@@ -2789,34 +2792,37 @@ CSSParserImpl::ParseAtRule(RuleAppendFun
   
   return true;
 }
 
 bool
 CSSParserImpl::ParseCharsetRule(RuleAppendFunc aAppendFunc,
                                 void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PECharsetRuleEOF);
     return false;
   }
 
   if (eCSSToken_String != mToken.mType) {
     UngetToken();
     REPORT_UNEXPECTED_TOKEN(PECharsetRuleNotString);
     return false;
   }
 
   nsAutoString charset = mToken.mIdent;
 
   if (!ExpectSymbol(';', true)) {
     return false;
   }
 
-  nsRefPtr<css::CharsetRule> rule = new css::CharsetRule(charset);
+  nsRefPtr<css::CharsetRule> rule = new css::CharsetRule(charset,
+                                                         linenum, colnum);
   (*aAppendFunc)(rule, aData);
 
   return true;
 }
 
 bool
 CSSParserImpl::ParseURLOrString(nsString& aURL)
 {
@@ -3151,18 +3157,20 @@ CSSParserImpl::ParseMediaQueryExpression
 }
 
 // Parse a CSS2 import rule: "@import STRING | URL [medium [, medium]]"
 bool
 CSSParserImpl::ParseImportRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsRefPtr<nsMediaList> media = new nsMediaList();
 
+  uint32_t linenum, colnum;
   nsAutoString url;
-  if (!ParseURLOrString(url)) {
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseURLOrString(url)) {
     REPORT_UNEXPECTED_TOKEN(PEImportNotURI);
     return false;
   }
 
   if (!ExpectSymbol(';', true)) {
     if (!GatherMedia(media, true) ||
         !ExpectSymbol(';', true)) {
       REPORT_UNEXPECTED_TOKEN(PEImportUnexpected);
@@ -3170,28 +3178,31 @@ CSSParserImpl::ParseImportRule(RuleAppen
       return false;
     }
 
     // Safe to assert this, since we ensured that there is something
     // other than the ';' coming after the @import's url() token.
     NS_ASSERTION(media->Length() != 0, "media list must be nonempty");
   }
 
-  ProcessImport(url, media, aAppendFunc, aData);
-  return true;
-}
-
+  ProcessImport(url, media, aAppendFunc, aData, linenum, colnum);
+  return true;
+}
 
 void
 CSSParserImpl::ProcessImport(const nsString& aURLSpec,
                              nsMediaList* aMedia,
                              RuleAppendFunc aAppendFunc,
-                             void* aData)
-{
-  nsRefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec);
+                             void* aData,
+                             uint32_t aLineNumber,
+                             uint32_t aColumnNumber)
+{
+  nsRefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec,
+                                                       aLineNumber,
+                                                       aColumnNumber);
   (*aAppendFunc)(rule, aData);
 
   // Diagnose bad URIs even if we don't have a child loader.
   nsCOMPtr<nsIURI> url;
   // Charset will be deduced from mBaseURI, which is more or less correct.
   nsresult rv = NS_NewURI(getter_AddRefs(url), aURLSpec, nullptr, mBaseURI);
 
   if (NS_FAILED(rv)) {
@@ -3252,20 +3263,21 @@ CSSParserImpl::ParseGroupRule(css::Group
   return true;
 }
 
 // Parse a CSS2 media rule: "@media medium [, medium] { ... }"
 bool
 CSSParserImpl::ParseMediaRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsRefPtr<nsMediaList> media = new nsMediaList();
-
-  if (GatherMedia(media, true)) {
+  uint32_t linenum, colnum;
+  if (GetNextTokenLocation(true, &linenum, &colnum) &&
+      GatherMedia(media, true)) {
     // XXXbz this could use better error reporting throughout the method
-    nsRefPtr<css::MediaRule> rule = new css::MediaRule();
+    nsRefPtr<css::MediaRule> rule = new css::MediaRule(linenum, colnum);
     // Append first, so when we do SetMedia() the rule
     // knows what its stylesheet is.
     if (ParseGroupRule(rule, aAppendFunc, aData)) {
       rule->SetMedia(media);
       return true;
     }
   }
 
@@ -3275,16 +3287,22 @@ CSSParserImpl::ParseMediaRule(RuleAppend
 // Parse a @-moz-document rule.  This is like an @media rule, but instead
 // of a medium it has a nonempty list of items where each item is either
 // url(), url-prefix(), or domain().
 bool
 CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   css::DocumentRule::URL *urls = nullptr;
   css::DocumentRule::URL **next = &urls;
+
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   do {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PEMozDocRuleEOF);
       delete urls;
       return false;
     }
         
     if (!(eCSSToken_URL == mToken.mType ||
@@ -3334,27 +3352,29 @@ CSSParserImpl::ParseMozDocumentRule(Rule
 
       // We could try to make the URL (as long as it's not domain())
       // canonical and absolute with NS_NewURI and GetSpec, but I'm
       // inclined to think we shouldn't.
       CopyUTF16toUTF8(mToken.mIdent, cur->url);
     }
   } while (ExpectSymbol(',', true));
 
-  nsRefPtr<css::DocumentRule> rule = new css::DocumentRule();
+  nsRefPtr<css::DocumentRule> rule = new css::DocumentRule(linenum, colnum);
   rule->SetURLs(urls);
 
   return ParseGroupRule(rule, aAppendFunc, aData);
 }
 
 // Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;"
 bool
 CSSParserImpl::ParseNameSpaceRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PEAtNSPrefixEOF);
     return false;
   }
 
   nsAutoString  prefix;
   nsAutoString  url;
 
   if (eCSSToken_Ident == mToken.mType) {
@@ -3368,56 +3388,62 @@ CSSParserImpl::ParseNameSpaceRule(RuleAp
     if (mHavePushBack) {
       REPORT_UNEXPECTED_TOKEN(PEAtNSUnexpected);
     } else {
       REPORT_UNEXPECTED_EOF(PEAtNSURIEOF);
     }
     return false;
   }
 
-  ProcessNameSpace(prefix, url, aAppendFunc, aData);
+  ProcessNameSpace(prefix, url, aAppendFunc, aData, linenum, colnum);
   return true;
 }
 
 void
 CSSParserImpl::ProcessNameSpace(const nsString& aPrefix,
                                 const nsString& aURLSpec,
                                 RuleAppendFunc aAppendFunc,
-                                void* aData)
+                                void* aData,
+                                uint32_t aLineNumber,
+                                uint32_t aColumnNumber)
 {
   nsCOMPtr<nsIAtom> prefix;
 
   if (!aPrefix.IsEmpty()) {
     prefix = do_GetAtom(aPrefix);
     if (!prefix) {
       NS_RUNTIMEABORT("do_GetAtom failed - out of memory?");
     }
   }
 
-  nsRefPtr<css::NameSpaceRule> rule = new css::NameSpaceRule(prefix, aURLSpec);
+  nsRefPtr<css::NameSpaceRule> rule = new css::NameSpaceRule(prefix, aURLSpec,
+                                                             aLineNumber,
+                                                             aColumnNumber);
   (*aAppendFunc)(rule, aData);
 
   // If this was the first namespace rule encountered, it will trigger
   // creation of a namespace map.
   if (!mNameSpaceMap) {
     mNameSpaceMap = mSheet->GetNameSpaceMap();
   }
 }
 
 // font-face-rule: '@font-face' '{' font-description '}'
 // font-description: font-descriptor+
 bool
 CSSParserImpl::ParseFontFaceRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!ExpectSymbol('{', true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PEBadFontBlockStart);
     return false;
   }
 
-  nsRefPtr<nsCSSFontFaceRule> rule(new nsCSSFontFaceRule());
+  nsRefPtr<nsCSSFontFaceRule> rule(new nsCSSFontFaceRule(linenum, colnum));
 
   for (;;) {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PEFontFaceEOF);
       break;
     }
     if (mToken.IsSymbol('}')) { // done!
       UngetToken();
@@ -3504,18 +3530,23 @@ CSSParserImpl::ParseFontDescriptor(nsCSS
 //   }
 //   ...
 // }
 
 bool
 CSSParserImpl::ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
                                           void* aData)
 {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   nsRefPtr<nsCSSFontFeatureValuesRule>
-               valuesRule(new nsCSSFontFeatureValuesRule());
+               valuesRule(new nsCSSFontFeatureValuesRule(linenum, colnum));
 
   // parse family list
   nsCSSValue fontlistValue;
 
   if (!ParseFamily(fontlistValue) ||
       fontlistValue.GetUnit() != eCSSUnit_FontFamilyList)
   {
     REPORT_UNEXPECTED_TOKEN(PEFFVNoFamily);
@@ -3721,34 +3752,37 @@ CSSParserImpl::ParseFontFeatureValueSet(
 
   aFeatureValuesRule->AddValueList(whichVariant, values);
   return true;
 }
 
 bool
 CSSParserImpl::ParseKeyframesRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PEKeyframeNameEOF);
     return false;
   }
 
   if (mToken.mType != eCSSToken_Ident) {
     REPORT_UNEXPECTED_TOKEN(PEKeyframeBadName);
     UngetToken();
     return false;
   }
   nsString name(mToken.mIdent);
 
   if (!ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PEKeyframeBrace);
     return false;
   }
 
-  nsRefPtr<nsCSSKeyframesRule> rule = new nsCSSKeyframesRule(name);
+  nsRefPtr<nsCSSKeyframesRule> rule = new nsCSSKeyframesRule(name,
+                                                             linenum, colnum);
 
   while (!ExpectSymbol('}', true)) {
     nsRefPtr<nsCSSKeyframeRule> kid = ParseKeyframeRule();
     if (kid) {
       rule->AppendStyleRule(kid);
     } else {
       OUTPUT_ERROR();
       SkipRuleSet(true);
@@ -3757,16 +3791,21 @@ CSSParserImpl::ParseKeyframesRule(RuleAp
 
   (*aAppendFunc)(rule, aData);
   return true;
 }
 
 bool
 CSSParserImpl::ParsePageRule(RuleAppendFunc aAppendFunc, void* aData)
 {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   // TODO: There can be page selectors after @page such as ":first", ":left".
   uint32_t parseFlags = eParseDeclaration_InBraces |
                         eParseDeclaration_AllowImportant;
 
   // Forbid viewport units in @page rules. See bug 811391.
   NS_ABORT_IF_FALSE(mViewportUnitsEnabled,
                     "Viewport units should be enabled outside of @page rules.");
   mViewportUnitsEnabled = false;
@@ -3775,42 +3814,44 @@ CSSParserImpl::ParsePageRule(RuleAppendF
                                                       eCSSContext_Page));
   mViewportUnitsEnabled = true;
 
   if (!declaration) {
     return false;
   }
 
   // Takes ownership of declaration.
-  nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration));
+  nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration),
+                                                   linenum, colnum);
 
   (*aAppendFunc)(rule, aData);
   return true;
 }
 
 already_AddRefed<nsCSSKeyframeRule>
 CSSParserImpl::ParseKeyframeRule()
 {
   InfallibleTArray<float> selectorList;
-  if (!ParseKeyframeSelectorList(selectorList)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseKeyframeSelectorList(selectorList)) {
     REPORT_UNEXPECTED(PEBadSelectorKeyframeRuleIgnored);
     return nullptr;
   }
 
   // Ignore !important in keyframe rules
   uint32_t parseFlags = eParseDeclaration_InBraces;
   nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
   if (!declaration) {
     return nullptr;
   }
 
   // Takes ownership of declaration, and steals contents of selectorList.
   nsRefPtr<nsCSSKeyframeRule> rule =
-    new nsCSSKeyframeRule(selectorList, Move(declaration));
-
+    new nsCSSKeyframeRule(selectorList, Move(declaration), linenum, colnum);
   return rule.forget();
 }
 
 bool
 CSSParserImpl::ParseKeyframeSelectorList(InfallibleTArray<float>& aSelectorList)
 {
   for (;;) {
     if (!GetToken(true)) {
@@ -3851,16 +3892,22 @@ CSSParserImpl::ParseKeyframeSelectorList
 //   ;
 bool
 CSSParserImpl::ParseSupportsRule(RuleAppendFunc aAppendFunc, void* aProcessData)
 {
   bool conditionMet = false;
   nsString condition;
 
   mScanner->StartRecording();
+
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   bool parsed = ParseSupportsCondition(conditionMet);
 
   if (!parsed) {
     mScanner->StopRecording();
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
@@ -3879,17 +3926,18 @@ CSSParserImpl::ParseSupportsRule(RuleApp
 
   // Remove spaces from the start and end of the recorded supports condition.
   condition.Trim(" ", true, true, false);
 
   // Record whether we are in a failing @supports, so that property parse
   // errors don't get reported.
   nsAutoFailingSupportsRule failing(this, conditionMet);
 
-  nsRefPtr<css::GroupRule> rule = new CSSSupportsRule(conditionMet, condition);
+  nsRefPtr<css::GroupRule> rule = new CSSSupportsRule(conditionMet, condition,
+                                                      linenum, colnum);
   return ParseGroupRule(rule, aAppendFunc, aProcessData);
 }
 
 // supports_condition
 //   : supports_condition_in_parens supports_condition_terms
 //   | supports_condition_negation
 //   ;
 bool
@@ -4141,27 +4189,31 @@ CSSParserImpl::ParseSupportsConditionTer
     }
   }
 }
 
 bool
 CSSParserImpl::ParseCounterStyleRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsAutoString name;
-  if (!ParseCounterStyleName(name, true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseCounterStyleName(name, true)) {
     REPORT_UNEXPECTED_TOKEN(PECounterStyleNotIdent);
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PECounterStyleBadBlockStart);
     return false;
   }
 
-  nsRefPtr<nsCSSCounterStyleRule> rule = new nsCSSCounterStyleRule(name);
+  nsRefPtr<nsCSSCounterStyleRule> rule = new nsCSSCounterStyleRule(name,
+                                                                   linenum,
+                                                                   colnum);
   for (;;) {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PECounterStyleEOF);
       break;
     }
     if (mToken.IsSymbol('}')) {
       break;
     }
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -211,18 +211,19 @@ GroupRuleRuleList::IndexedGetter(uint32_
 //
 
 // Must be outside namespace
 DOMCI_DATA(CSSCharsetRule, css::CharsetRule)
 
 namespace mozilla {
 namespace css {
 
-CharsetRule::CharsetRule(const nsAString& aEncoding)
-  : Rule(),
+CharsetRule::CharsetRule(const nsAString& aEncoding,
+                         uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber),
     mEncoding(aEncoding)
 {
 }
 
 CharsetRule::CharsetRule(const CharsetRule& aCopy)
   : Rule(aCopy),
     mEncoding(aCopy.mEncoding)
 {
@@ -331,18 +332,19 @@ CharsetRule::SizeOfIncludingThis(MallocS
   // worthwhile:
   // - mEncoding
 }
 
 // -------------------------------------------
 // ImportRule
 //
 
-ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec)
-  : Rule()
+ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
+                       uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber)
   , mURLSpec(aURLSpec)
   , mMedia(aMedia)
 {
   // XXXbz This is really silly.... the mMedia here will be replaced
   // with itself if we manage to load a sheet.  Which should really
   // never fail nowadays, in sane cases.
 }
 
@@ -519,18 +521,18 @@ ImportRule::SizeOfIncludingThis(MallocSi
 } // namespace mozilla
 
 // must be outside the namespace
 DOMCI_DATA(CSSImportRule, css::ImportRule)
 
 namespace mozilla {
 namespace css {
 
-GroupRule::GroupRule()
-  : Rule()
+GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber)
 {
 }
 
 static bool
 SetParentRuleReference(Rule* aRule, void* aParentRule)
 {
   GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
   aRule->SetParentRule(parentRule);
@@ -765,17 +767,18 @@ GroupRule::SizeOfExcludingThis(MallocSiz
   // worthwhile:
   // - mRuleCollection
 }
 
 
 // -------------------------------------------
 // nsICSSMediaRule
 //
-MediaRule::MediaRule()
+MediaRule::MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 MediaRule::MediaRule(const MediaRule& aCopy)
   : GroupRule(aCopy)
 {
   if (aCopy.mMedia) {
     mMedia = aCopy.mMedia->Clone();
@@ -991,17 +994,18 @@ MediaRule::AppendConditionText(nsAString
 } // namespace mozilla
 
 // Must be outside namespace
 DOMCI_DATA(CSSMediaRule, css::MediaRule)
 
 namespace mozilla {
 namespace css {
 
-DocumentRule::DocumentRule()
+DocumentRule::DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 DocumentRule::DocumentRule(const DocumentRule& aCopy)
   : GroupRule(aCopy)
   , mURLs(new URL(*aCopy.mURLs))
 {
 }
@@ -1247,18 +1251,19 @@ DOMCI_DATA(CSSMozDocumentRule, css::Docu
 
 // -------------------------------------------
 // NameSpaceRule
 //
 
 namespace mozilla {
 namespace css {
 
-NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec)
-  : Rule(),
+NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
+                             uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber),
     mPrefix(aPrefix),
     mURLSpec(aURLSpec)
 {
 }
 
 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
   : Rule(aCopy),
     mPrefix(aCopy.mPrefix),
@@ -2916,19 +2921,21 @@ nsCSSPageRule::ChangeDeclaration(css::De
 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
 namespace mozilla {
 
 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
-                                 const nsString& aCondition)
-  : mUseGroup(aConditionMet),
-    mCondition(aCondition)
+                                 const nsString& aCondition,
+                                 uint32_t aLineNumber, uint32_t aColumnNumber)
+  : css::GroupRule(aLineNumber, aColumnNumber)
+  , mUseGroup(aConditionMet)
+  , mCondition(aCondition)
 {
 }
 
 CSSSupportsRule::~CSSSupportsRule()
 {
 }
 
 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -42,17 +42,17 @@ namespace mozilla {
 class ErrorResult;
 
 namespace css {
 
 class MediaRule MOZ_FINAL : public GroupRule,
                             public nsIDOMCSSMediaRule
 {
 public:
-  MediaRule();
+  MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   MediaRule(const MediaRule& aCopy);
   ~MediaRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
@@ -100,17 +100,17 @@ protected:
 
   nsRefPtr<nsMediaList> mMedia;
 };
 
 class DocumentRule MOZ_FINAL : public GroupRule,
                                public nsIDOMCSSMozDocumentRule
 {
 public:
-  DocumentRule();
+  DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   DocumentRule(const DocumentRule& aCopy);
   ~DocumentRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
@@ -226,17 +226,18 @@ private:
   // nsCSSFontFaceRule.
   void* operator new(size_t size) CPP_THROW_NEW;
 };
 
 class nsCSSFontFaceRule MOZ_FINAL : public mozilla::css::Rule,
                                     public nsIDOMCSSFontFaceRule
 {
 public:
-  nsCSSFontFaceRule() {}
+  nsCSSFontFaceRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFaceRule(const nsCSSFontFaceRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSFontFaceRule,
                                                          mozilla::css::Rule)
@@ -291,17 +292,18 @@ nsCSSFontFaceStyleDecl::ContainingRule()
     (reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 class nsCSSFontFeatureValuesRule MOZ_FINAL :
                                        public mozilla::css::Rule,
                                        public nsIDOMCSSFontFeatureValuesRule
 {
 public:
-  nsCSSFontFeatureValuesRule() {}
+  nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy),
       mFamilyList(aCopy.mFamilyList),
       mFeatureValues(aCopy.mFeatureValues) {}
 
   NS_DECL_ISUPPORTS
@@ -354,17 +356,18 @@ protected:
 
 namespace mozilla {
 namespace css {
 
 class CharsetRule MOZ_FINAL : public Rule,
                               public nsIDOMCSSCharsetRule
 {
 public:
-  CharsetRule(const nsAString& aEncoding);
+  CharsetRule(const nsAString& aEncoding,
+              uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // For |Clone|
   CharsetRule(const CharsetRule& aCopy);
   ~CharsetRule() {}
 
 public:
   NS_DECL_ISUPPORTS
 
@@ -424,18 +427,20 @@ protected:
 };
 
 class nsCSSKeyframeRule MOZ_FINAL : public mozilla::css::Rule,
                                     public nsIDOMMozCSSKeyframeRule
 {
 public:
   // WARNING: Steals the contents of aKeys *and* aDeclaration
   nsCSSKeyframeRule(InfallibleTArray<float>& aKeys,
-                    nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
-    : mDeclaration(mozilla::Move(aDeclaration))
+                    nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
+                    uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mDeclaration(mozilla::Move(aDeclaration))
   {
     mKeys.SwapElements(aKeys);
   }
 private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -472,18 +477,20 @@ private:
   // lazily created when needed:
   nsRefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
 };
 
 class nsCSSKeyframesRule MOZ_FINAL : public mozilla::css::GroupRule,
                                      public nsIDOMMozCSSKeyframesRule
 {
 public:
-  nsCSSKeyframesRule(const nsSubstring& aName)
-    : mName(aName)
+  nsCSSKeyframesRule(const nsSubstring& aName,
+                     uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::GroupRule(aLineNumber, aColumnNumber)
+    , mName(aName)
   {
   }
 private:
   nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
   ~nsCSSKeyframesRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -552,19 +559,21 @@ protected:
   nsCSSPageRule *mRule;
 };
 
 class nsCSSPageRule MOZ_FINAL : public mozilla::css::Rule,
                                 public nsIDOMCSSPageRule
 {
 public:
   // WARNING: Steals the contents of aDeclaration
-  nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
-    : mDeclaration(mozilla::Move(aDeclaration)),
-      mImportantRule(nullptr)
+  nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
+                uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mDeclaration(mozilla::Move(aDeclaration))
+    , mImportantRule(nullptr)
   {
   }
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSPageRule, nsIDOMCSSPageRule)
@@ -600,17 +609,18 @@ private:
 };
 
 namespace mozilla {
 
 class CSSSupportsRule : public css::GroupRule,
                         public nsIDOMCSSSupportsRule
 {
 public:
-  CSSSupportsRule(bool aConditionMet, const nsString& aCondition);
+  CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
+                  uint32_t aLineNumber, uint32_t aColumnNumber);
   CSSSupportsRule(const CSSSupportsRule& aCopy);
 
   // nsIStyleRule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
@@ -651,19 +661,21 @@ protected:
 };
 
 } // namespace mozilla
 
 class nsCSSCounterStyleRule MOZ_FINAL : public mozilla::css::Rule,
                                         public nsIDOMCSSCounterStyleRule
 {
 public:
-  explicit nsCSSCounterStyleRule(const nsAString& aName)
-    : mName(aName),
-      mGeneration(0)
+  explicit nsCSSCounterStyleRule(const nsAString& aName,
+                                 uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mName(aName)
+    , mGeneration(0)
   {
   }
 
 private:
   nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy);
   ~nsCSSCounterStyleRule();
 
 public:
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -123,17 +123,17 @@ nsDOMCSSAttributeDeclaration::GetCSSDecl
   }
   if (!aAllocate) {
     return nullptr;
   }
 
   // cannot fail
   css::Declaration *decl = new css::Declaration();
   decl->InitializeEmpty();
-  nsRefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl);
+  nsRefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl, 0, 0);
 
   // this *can* fail (inside SetAttrAndNotify, at least).
   nsresult rv;
   if (mIsSMILOverride)
     rv = mElement->SetSMILOverrideStyleRule(newRule, false);
   else
     rv = mElement->SetInlineStyleRule(newRule, nullptr, false);