tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

error_reporter.rs (23567B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Wrapper around Gecko's CSS error reporting mechanism.
      6 
      7 #![allow(unsafe_code)]
      8 
      9 use cssparser::{serialize_identifier, CowRcStr, ToCss};
     10 use cssparser::{BasicParseErrorKind, ParseError, ParseErrorKind, SourceLocation, Token};
     11 use selectors::parser::SelectorParseErrorKind;
     12 use selectors::SelectorList;
     13 use std::ffi::CStr;
     14 use std::ptr;
     15 use style::error_reporting::{ContextualParseError, ParseErrorReporter};
     16 use style::gecko_bindings::bindings;
     17 use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData;
     18 use style::gecko_bindings::structs::{nsIURI, Loader, StyleSheet as DomStyleSheet};
     19 use style::selector_parser::SelectorImpl;
     20 use style::stylesheets::UrlExtraData;
     21 use style_traits::{PropertySyntaxParseError, StyleParseErrorKind, ValueParseErrorKind};
     22 
     23 pub type ErrorKind<'i> = ParseErrorKind<'i, StyleParseErrorKind<'i>>;
     24 
     25 /// An error reporter with all the data we need to report errors.
     26 pub struct ErrorReporter {
     27    window_id: u64,
     28    uri: *mut nsIURI,
     29 }
     30 
     31 impl ErrorReporter {
     32    /// Create a new instance of the Gecko error reporter, if error reporting is
     33    /// enabled.
     34    pub fn new(
     35        sheet: *mut DomStyleSheet,
     36        loader: *mut Loader,
     37        extra_data: *mut RawUrlExtraData,
     38    ) -> Option<Self> {
     39        let mut window_id = 0;
     40 
     41        let enabled =
     42            unsafe { bindings::Gecko_ErrorReportingEnabled(sheet, loader, &mut window_id) };
     43 
     44        if !enabled {
     45            return None;
     46        }
     47 
     48        let uri = unsafe {
     49            extra_data
     50                .as_ref()
     51                .map(|d| d.mBaseURI.raw())
     52                .unwrap_or(ptr::null_mut())
     53        };
     54 
     55        Some(ErrorReporter { window_id, uri })
     56    }
     57 }
     58 
     59 enum ErrorString<'a> {
     60    Snippet(CowRcStr<'a>),
     61    Ident(CowRcStr<'a>),
     62    UnexpectedToken(Token<'a>),
     63 }
     64 
     65 impl<'a> ErrorString<'a> {
     66    fn into_str(self) -> CowRcStr<'a> {
     67        match self {
     68            ErrorString::Snippet(s) => s,
     69            ErrorString::UnexpectedToken(t) => t.to_css_string().into(),
     70            ErrorString::Ident(i) => {
     71                let mut s = String::new();
     72                serialize_identifier(&i, &mut s).unwrap();
     73                s.into()
     74            },
     75        }
     76    }
     77 }
     78 
     79 #[derive(Debug)]
     80 enum Action {
     81    Nothing,
     82    Skip,
     83    Drop,
     84 }
     85 
     86 trait ErrorHelpers<'a> {
     87    fn error_data(self) -> (CowRcStr<'a>, ErrorKind<'a>);
     88    fn error_params(self) -> ErrorParams<'a>;
     89    fn selectors(&self) -> &'a [SelectorList<SelectorImpl>];
     90    fn to_gecko_message(&self) -> (Option<&'static CStr>, &'static CStr, Action);
     91 }
     92 
     93 fn extract_error_param<'a>(err: ErrorKind<'a>) -> Option<ErrorString<'a>> {
     94    Some(match err {
     95        ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(t)) => {
     96            ErrorString::UnexpectedToken(t)
     97        },
     98 
     99        ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(i)) => {
    100            let mut s = String::from("@");
    101            serialize_identifier(&i, &mut s).unwrap();
    102            ErrorString::Snippet(s.into())
    103        },
    104 
    105        ParseErrorKind::Custom(StyleParseErrorKind::OtherInvalidValue(property)) => {
    106            ErrorString::Snippet(property)
    107        },
    108 
    109        ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(
    110            SelectorParseErrorKind::UnexpectedIdent(ident),
    111        )) => ErrorString::Ident(ident),
    112 
    113        ParseErrorKind::Custom(StyleParseErrorKind::UnknownProperty(property)) => {
    114            ErrorString::Ident(property)
    115        },
    116 
    117        ParseErrorKind::Custom(StyleParseErrorKind::UnexpectedTokenWithinNamespace(token)) => {
    118            ErrorString::UnexpectedToken(token)
    119        },
    120 
    121        _ => return None,
    122    })
    123 }
    124 
    125 #[derive(Default)]
    126 struct ErrorParams<'a> {
    127    prefix_param: Option<ErrorString<'a>>,
    128    main_param: Option<ErrorString<'a>>,
    129 }
    130 
    131 /// If an error parameter is present in the given error, return it. Additionally return
    132 /// a second parameter if it exists, for use in the prefix for the eventual error message.
    133 fn extract_error_params<'a>(err: ErrorKind<'a>) -> Option<ErrorParams<'a>> {
    134    let (main, prefix) = match err {
    135        ParseErrorKind::Custom(StyleParseErrorKind::InvalidColor(property, token))
    136        | ParseErrorKind::Custom(StyleParseErrorKind::InvalidFilter(property, token)) => (
    137            Some(ErrorString::Snippet(property.into())),
    138            Some(ErrorString::UnexpectedToken(token)),
    139        ),
    140 
    141        ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureName(ident)) => {
    142            (Some(ErrorString::Ident(ident)), None)
    143        },
    144 
    145        ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(token))
    146        | ParseErrorKind::Custom(StyleParseErrorKind::ValueError(
    147            ValueParseErrorKind::InvalidColor(token),
    148        )) => (Some(ErrorString::UnexpectedToken(token)), None),
    149 
    150        ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(err)) => match err {
    151            SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t)
    152            | SelectorParseErrorKind::BadValueInAttr(t)
    153            | SelectorParseErrorKind::ExpectedBarInAttr(t)
    154            | SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t)
    155            | SelectorParseErrorKind::InvalidQualNameInAttr(t)
    156            | SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t)
    157            | SelectorParseErrorKind::PseudoElementExpectedIdent(t)
    158            | SelectorParseErrorKind::NoIdentForPseudo(t)
    159            | SelectorParseErrorKind::ClassNeedsIdent(t)
    160            | SelectorParseErrorKind::PseudoElementExpectedColon(t) => {
    161                (None, Some(ErrorString::UnexpectedToken(t)))
    162            },
    163            SelectorParseErrorKind::ExpectedNamespace(namespace) => {
    164                (None, Some(ErrorString::Ident(namespace)))
    165            },
    166            SelectorParseErrorKind::UnsupportedPseudoClassOrElement(p) => {
    167                (None, Some(ErrorString::Ident(p)))
    168            },
    169            SelectorParseErrorKind::EmptySelector | SelectorParseErrorKind::DanglingCombinator => {
    170                (None, None)
    171            },
    172            err => (
    173                Some(extract_error_param(ParseErrorKind::Custom(
    174                    StyleParseErrorKind::SelectorError(err),
    175                ))?),
    176                None,
    177            ),
    178        },
    179        err => (Some(extract_error_param(err)?), None),
    180    };
    181    Some(ErrorParams {
    182        main_param: main,
    183        prefix_param: prefix,
    184    })
    185 }
    186 
    187 impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
    188    fn error_data(self) -> (CowRcStr<'a>, ErrorKind<'a>) {
    189        match self {
    190            ContextualParseError::UnsupportedPropertyDeclaration(s, err, _)
    191            | ContextualParseError::UnsupportedPropertyDescriptor(s, err)
    192            | ContextualParseError::UnsupportedFontFaceDescriptor(s, err)
    193            | ContextualParseError::UnsupportedFontFeatureValuesDescriptor(s, err)
    194            | ContextualParseError::UnsupportedFontPaletteValuesDescriptor(s, err)
    195            | ContextualParseError::InvalidKeyframeRule(s, err)
    196            | ContextualParseError::InvalidFontFeatureValuesRule(s, err)
    197            | ContextualParseError::InvalidRule(s, err)
    198            | ContextualParseError::UnsupportedRule(s, err)
    199            | ContextualParseError::UnsupportedViewportDescriptorDeclaration(s, err)
    200            | ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(s, err)
    201            | ContextualParseError::InvalidMediaRule(s, err)
    202            | ContextualParseError::UnsupportedValue(s, err) => (s.into(), err.kind),
    203            ContextualParseError::NeverMatchingHostSelector(s)
    204            | ContextualParseError::InvalidCounterStyleWithoutSymbols(s)
    205            | ContextualParseError::InvalidCounterStyleNotEnoughSymbols(s) => (
    206                s.into(),
    207                ParseErrorKind::Custom(StyleParseErrorKind::UnspecifiedError.into()),
    208            ),
    209            ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols
    210            | ContextualParseError::InvalidCounterStyleExtendsWithSymbols
    211            | ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols => (
    212                "".into(),
    213                ParseErrorKind::Custom(StyleParseErrorKind::UnspecifiedError.into()),
    214            ),
    215        }
    216    }
    217 
    218    fn error_params(self) -> ErrorParams<'a> {
    219        let (s, error) = self.error_data();
    220        let mut params = extract_error_params(error).unwrap_or_default();
    221        params
    222            .main_param
    223            .get_or_insert_with(|| ErrorString::Snippet(s));
    224        params
    225    }
    226 
    227    fn selectors(&self) -> &'a [SelectorList<SelectorImpl>] {
    228        match *self {
    229            ContextualParseError::UnsupportedPropertyDeclaration(_, _, selectors) => selectors,
    230            _ => &[],
    231        }
    232    }
    233 
    234    fn to_gecko_message(&self) -> (Option<&'static CStr>, &'static CStr, Action) {
    235        let (msg, action): (&CStr, Action) = match *self {
    236            ContextualParseError::UnsupportedPropertyDeclaration(
    237                _,
    238                ParseError {
    239                    kind: ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(_)),
    240                    ..
    241                },
    242                _,
    243            )
    244            | ContextualParseError::UnsupportedPropertyDeclaration(
    245                _,
    246                ParseError {
    247                    kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(_)),
    248                    ..
    249                },
    250                _,
    251            ) => (cstr!("PEParseDeclarationDeclExpected"), Action::Skip),
    252            ContextualParseError::UnsupportedPropertyDeclaration(
    253                _,
    254                ParseError {
    255                    kind: ParseErrorKind::Custom(ref err),
    256                    ..
    257                },
    258                _,
    259            ) => match *err {
    260                StyleParseErrorKind::InvalidColor(_, _) => {
    261                    return (
    262                        Some(cstr!("PEColorNotColor")),
    263                        cstr!("PEValueParsingError"),
    264                        Action::Drop,
    265                    );
    266                },
    267                StyleParseErrorKind::InvalidFilter(_, _) => {
    268                    return (
    269                        Some(cstr!("PEExpectedNoneOrURLOrFilterFunction")),
    270                        cstr!("PEValueParsingError"),
    271                        Action::Drop,
    272                    );
    273                },
    274                StyleParseErrorKind::OtherInvalidValue(_) => {
    275                    (cstr!("PEValueParsingError"), Action::Drop)
    276                },
    277                StyleParseErrorKind::UnexpectedImportantDeclaration => {
    278                    (cstr!("PEImportantDeclError"), Action::Drop)
    279                },
    280                _ => (cstr!("PEUnknownProperty"), Action::Drop),
    281            },
    282            ContextualParseError::UnsupportedPropertyDeclaration(..) => {
    283                (cstr!("PEUnknownProperty"), Action::Drop)
    284            },
    285            ContextualParseError::UnsupportedFontFaceDescriptor(..) => {
    286                (cstr!("PEUnknownFontDesc"), Action::Skip)
    287            },
    288            ContextualParseError::InvalidKeyframeRule(..) => {
    289                (cstr!("PEKeyframeBadName"), Action::Nothing)
    290            },
    291            ContextualParseError::InvalidRule(
    292                _,
    293                ParseError {
    294                    kind:
    295                        ParseErrorKind::Custom(StyleParseErrorKind::UnexpectedTokenWithinNamespace(_)),
    296                    ..
    297                },
    298            ) => (cstr!("PEAtNSUnexpected"), Action::Nothing),
    299            ContextualParseError::InvalidRule(
    300                _,
    301                ParseError {
    302                    kind: ParseErrorKind::Custom(StyleParseErrorKind::DisallowedImportRule),
    303                    ..
    304                },
    305            ) => (cstr!("PEDisallowedImportRule"), Action::Nothing),
    306            ContextualParseError::InvalidRule(
    307                _,
    308                ParseError {
    309                    kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(_)),
    310                    ..
    311                },
    312            ) => (cstr!("PEUnknownAtRule"), Action::Nothing),
    313            ContextualParseError::InvalidRule(_, ref err) => {
    314                let prefix = match err.kind {
    315                    ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(ref err)) => {
    316                        match *err {
    317                            SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(_) => {
    318                                Some(cstr!("PEAttSelUnexpected"))
    319                            },
    320                            SelectorParseErrorKind::ExpectedBarInAttr(_) => {
    321                                Some(cstr!("PEAttSelNoBar"))
    322                            },
    323                            SelectorParseErrorKind::BadValueInAttr(_) => {
    324                                Some(cstr!("PEAttSelBadValue"))
    325                            },
    326                            SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(_) => {
    327                                Some(cstr!("PEAttributeNameOrNamespaceExpected"))
    328                            },
    329                            SelectorParseErrorKind::InvalidQualNameInAttr(_) => {
    330                                Some(cstr!("PEAttributeNameExpected"))
    331                            },
    332                            SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(_) => {
    333                                Some(cstr!("PETypeSelNotType"))
    334                            },
    335                            SelectorParseErrorKind::ExpectedNamespace(_) => {
    336                                Some(cstr!("PEUnknownNamespacePrefix"))
    337                            },
    338                            SelectorParseErrorKind::EmptySelector => {
    339                                Some(cstr!("PESelectorGroupNoSelector"))
    340                            },
    341                            SelectorParseErrorKind::DanglingCombinator => {
    342                                Some(cstr!("PESelectorGroupExtraCombinator"))
    343                            },
    344                            SelectorParseErrorKind::UnsupportedPseudoClassOrElement(_) => {
    345                                Some(cstr!("PEPseudoSelUnknown"))
    346                            },
    347                            SelectorParseErrorKind::PseudoElementExpectedColon(_) => {
    348                                Some(cstr!("PEPseudoSelEndOrUserActionPC"))
    349                            },
    350                            SelectorParseErrorKind::NoIdentForPseudo(_) => {
    351                                Some(cstr!("PEPseudoClassArgNotIdent"))
    352                            },
    353                            SelectorParseErrorKind::PseudoElementExpectedIdent(_) => {
    354                                Some(cstr!("PEPseudoSelBadName"))
    355                            },
    356                            SelectorParseErrorKind::ClassNeedsIdent(_) => {
    357                                Some(cstr!("PEClassSelNotIdent"))
    358                            },
    359                            _ => None,
    360                        }
    361                    },
    362                    ParseErrorKind::Custom(
    363                        StyleParseErrorKind::PropertySyntaxField(_)
    364                        | StyleParseErrorKind::PropertyInheritsField(_),
    365                    ) => {
    366                        // Keeps PEBadSelectorRSIgnored from being reported when a syntax descriptor
    367                        // error or inherits descriptor error was already reported.
    368                        return (None, cstr!(""), Action::Nothing);
    369                    },
    370                    _ => None,
    371                };
    372                return (prefix, cstr!("PEBadSelectorRSIgnored"), Action::Nothing);
    373            },
    374            ContextualParseError::InvalidMediaRule(_, ref err) => {
    375                let err: &CStr = match err.kind {
    376                    ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureName(
    377                        ..,
    378                    )) => cstr!("PEMQExpectedFeatureName"),
    379                    ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureValue) => {
    380                        cstr!("PEMQExpectedFeatureValue")
    381                    },
    382                    ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryUnexpectedOperator) => {
    383                        cstr!("PEMQUnexpectedOperator")
    384                    },
    385                    ParseErrorKind::Custom(StyleParseErrorKind::RangedExpressionWithNoValue) => {
    386                        cstr!("PEMQNoMinMaxWithoutValue")
    387                    },
    388                    _ => cstr!("PEMQUnexpectedToken"),
    389                };
    390                (err, Action::Nothing)
    391            },
    392            ContextualParseError::UnsupportedRule(..) => (cstr!("PEDeclDropped"), Action::Nothing),
    393            ContextualParseError::NeverMatchingHostSelector(..) => {
    394                (cstr!("PENeverMatchingHostSelector"), Action::Nothing)
    395            },
    396            ContextualParseError::UnsupportedViewportDescriptorDeclaration(..)
    397            | ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(..)
    398            | ContextualParseError::InvalidCounterStyleWithoutSymbols(..)
    399            | ContextualParseError::InvalidCounterStyleNotEnoughSymbols(..)
    400            | ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols
    401            | ContextualParseError::InvalidCounterStyleExtendsWithSymbols
    402            | ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols
    403            | ContextualParseError::UnsupportedPropertyDescriptor(..)
    404            | ContextualParseError::UnsupportedFontFeatureValuesDescriptor(..)
    405            | ContextualParseError::UnsupportedFontPaletteValuesDescriptor(..)
    406            | ContextualParseError::InvalidFontFeatureValuesRule(..) => {
    407                (cstr!("PEUnknownAtRule"), Action::Skip)
    408            },
    409            ContextualParseError::UnsupportedValue(_, ParseError { ref kind, .. }) => {
    410                match *kind {
    411                    ParseErrorKind::Custom(StyleParseErrorKind::ValueError(
    412                        ValueParseErrorKind::InvalidColor(..),
    413                    )) => (cstr!("PEColorNotColor"), Action::Nothing),
    414                    ParseErrorKind::Custom(StyleParseErrorKind::PropertySyntaxField(ref kind)) => {
    415                        let name = match kind {
    416                            PropertySyntaxParseError::NoSyntax => {
    417                                cstr!("PEPRSyntaxFieldMissing")
    418                            },
    419                            PropertySyntaxParseError::EmptyInput => {
    420                                cstr!("PEPRSyntaxFieldEmptyInput")
    421                            },
    422                            PropertySyntaxParseError::ExpectedPipeBetweenComponents => {
    423                                cstr!("PEPRSyntaxFieldExpectedPipe")
    424                            },
    425                            PropertySyntaxParseError::InvalidNameStart => {
    426                                cstr!("PEPRSyntaxFieldInvalidNameStart")
    427                            },
    428                            PropertySyntaxParseError::InvalidName => {
    429                                cstr!("PEPRSyntaxFieldInvalidName")
    430                            },
    431                            PropertySyntaxParseError::UnclosedDataTypeName => {
    432                                cstr!("PEPRSyntaxFieldUnclosedDataTypeName")
    433                            },
    434                            PropertySyntaxParseError::UnexpectedEOF => {
    435                                cstr!("PEPRSyntaxFieldUnexpectedEOF")
    436                            },
    437                            PropertySyntaxParseError::UnknownDataTypeName => {
    438                                cstr!("PEPRSyntaxFieldUnknownDataTypeName")
    439                            },
    440                        };
    441                        (name, Action::Nothing)
    442                    },
    443                    ParseErrorKind::Custom(StyleParseErrorKind::PropertyInheritsField(
    444                        ref kind,
    445                    )) => {
    446                        let name = match kind {
    447                            style_traits::PropertyInheritsParseError::NoInherits => {
    448                                cstr!("PEPRInheritsFieldMissing")
    449                            },
    450                            style_traits::PropertyInheritsParseError::InvalidInherits => {
    451                                cstr!("PEPRInheritsFieldInvalid")
    452                            },
    453                        };
    454                        (name, Action::Nothing)
    455                    },
    456                    _ => {
    457                        // Not the best error message, since we weren't parsing
    458                        // a declaration, just a value. But we don't produce
    459                        // UnsupportedValue errors other than InvalidColors
    460                        // currently.
    461                        debug_assert!(false, "should use a more specific error message");
    462                        (cstr!("PEDeclDropped"), Action::Nothing)
    463                    },
    464                }
    465            },
    466        };
    467        (None, msg, action)
    468    }
    469 }
    470 
    471 impl ErrorReporter {
    472    pub fn report(&self, location: SourceLocation, error: ContextualParseError) {
    473        let (pre, name, action) = error.to_gecko_message();
    474        let suffix = match action {
    475            Action::Nothing => ptr::null(),
    476            Action::Skip => cstr!("PEDeclSkipped").as_ptr(),
    477            Action::Drop => cstr!("PEDeclDropped").as_ptr(),
    478        };
    479        let selectors = error.selectors();
    480        let desugared_selector_list = match selectors.len() {
    481            0 => None,
    482            1 => Some(selectors[0].to_css_string()),
    483            _ => {
    484                let mut desugared = selectors.last().unwrap().clone();
    485                for parent in selectors.iter().rev().skip(1) {
    486                    desugared = desugared.replace_parent_selector(&parent);
    487                }
    488                Some(desugared.to_css_string())
    489            },
    490        };
    491        let selector_list_ptr = desugared_selector_list
    492            .as_ref()
    493            .map_or(ptr::null(), |s| s.as_ptr()) as *const _;
    494        let params = error.error_params();
    495        let param = params.main_param;
    496        let pre_param = params.prefix_param;
    497        let param = param.map(|p| p.into_str());
    498        let pre_param = pre_param.map(|p| p.into_str());
    499        let param_ptr = param.as_ref().map_or(ptr::null(), |p| p.as_ptr());
    500        let pre_param_ptr = pre_param.as_ref().map_or(ptr::null(), |p| p.as_ptr());
    501        unsafe {
    502            bindings::Gecko_ReportUnexpectedCSSError(
    503                self.window_id,
    504                self.uri,
    505                name.as_ptr() as *const _,
    506                param_ptr as *const _,
    507                param.as_ref().map_or(0, |p| p.len()) as u32,
    508                pre.map_or(ptr::null(), |p| p.as_ptr()) as *const _,
    509                pre_param_ptr as *const _,
    510                pre_param.as_ref().map_or(0, |p| p.len()) as u32,
    511                suffix as *const _,
    512                selector_list_ptr,
    513                desugared_selector_list
    514                    .as_ref()
    515                    .map_or(0, |string| string.len()) as u32,
    516                location.line,
    517                location.column,
    518            );
    519        }
    520    }
    521 }
    522 
    523 impl ParseErrorReporter for ErrorReporter {
    524    fn report_error(
    525        &self,
    526        _url: &UrlExtraData,
    527        location: SourceLocation,
    528        error: ContextualParseError,
    529    ) {
    530        self.report(location, error)
    531    }
    532 }