PropertyDeclarationParseResult -> Result<(), PropertyDeclarationParseError>

This commit is contained in:
Simon Sapin 2017-03-07 16:19:06 +01:00
parent da6316fbe3
commit 7455ad5eb4
5 changed files with 30 additions and 45 deletions

View file

@ -13,7 +13,6 @@ use parser::{ParserContext, ParserContextExtraData, log_css_error};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
use properties::{PropertyDeclarationId, LonghandId, DeclaredValue}; use properties::{PropertyDeclarationId, LonghandId, DeclaredValue};
use properties::LonghandIdSet; use properties::LonghandIdSet;
use properties::PropertyDeclarationParseResult;
use properties::animated_properties::TransitionProperty; use properties::animated_properties::TransitionProperty;
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
use std::fmt; use std::fmt;
@ -407,12 +406,9 @@ impl<'a, 'b> DeclarationParser for KeyframeDeclarationParser<'a, 'b> {
fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> { fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> {
let id = try!(PropertyId::parse(name.into())); let id = try!(PropertyId::parse(name.into()));
let old_len = self.declarations.len(); let old_len = self.declarations.len();
match PropertyDeclaration::parse(id, self.context, input, &mut self.declarations, true) { if PropertyDeclaration::parse(id, self.context, input, &mut self.declarations, true).is_err() {
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {} self.declarations.truncate(old_len);
_ => { return Err(())
self.declarations.truncate(old_len);
return Err(());
}
} }
// In case there is still unparsed text in the declaration, we should roll back. // In case there is still unparsed text in the declaration, we should roll back.
if !input.is_exhausted() { if !input.is_exhausted() {

View file

@ -561,8 +561,8 @@ pub fn parse_one_declaration(id: PropertyId,
Parser::new(input).parse_entirely(|parser| { Parser::new(input).parse_entirely(|parser| {
let mut results = vec![]; let mut results = vec![];
match PropertyDeclaration::parse(id, &context, parser, &mut results, false) { match PropertyDeclaration::parse(id, &context, parser, &mut results, false) {
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(results), Ok(()) => Ok(results),
_ => Err(()) Err(_) => Err(())
} }
}) })
} }
@ -592,10 +592,8 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
let id = try!(PropertyId::parse(name.into())); let id = try!(PropertyId::parse(name.into()));
let old_len = self.declarations.len(); let old_len = self.declarations.len();
let parse_result = input.parse_until_before(Delimiter::Bang, |input| { let parse_result = input.parse_until_before(Delimiter::Bang, |input| {
match PropertyDeclaration::parse(id, self.context, input, &mut self.declarations, false) { PropertyDeclaration::parse(id, self.context, input, &mut self.declarations, false)
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(()), .map_err(|_| ())
_ => Err(())
}
}); });
if let Err(_) = parse_result { if let Err(_) = parse_result {
// rollback // rollback

View file

@ -886,7 +886,7 @@ impl HasViewportPercentage for PropertyDeclaration {
/// The result of parsing a property declaration. /// The result of parsing a property declaration.
#[derive(Eq, PartialEq, Copy, Clone)] #[derive(Eq, PartialEq, Copy, Clone)]
pub enum PropertyDeclarationParseResult { pub enum PropertyDeclarationParseError {
/// The property declaration was for an unknown property. /// The property declaration was for an unknown property.
UnknownProperty, UnknownProperty,
/// The property declaration was for a disabled experimental property. /// The property declaration was for a disabled experimental property.
@ -898,8 +898,6 @@ pub enum PropertyDeclarationParseResult {
/// ///
/// See: https://drafts.csswg.org/css-animations/#keyframes /// See: https://drafts.csswg.org/css-animations/#keyframes
AnimationPropertyInKeyframeBlock, AnimationPropertyInKeyframeBlock,
/// The declaration was either valid or ignored.
ValidOrIgnoredDeclaration,
} }
impl fmt::Debug for PropertyDeclaration { impl fmt::Debug for PropertyDeclaration {
@ -933,7 +931,7 @@ impl ToCss for PropertyDeclaration {
% if property.experimental and product == "servo": % if property.experimental and product == "servo":
if !PREFS.get("${property.experimental}") if !PREFS.get("${property.experimental}")
.as_boolean().unwrap_or(false) { .as_boolean().unwrap_or(false) {
return PropertyDeclarationParseResult::ExperimentalProperty return Err(PropertyDeclarationParseError::ExperimentalProperty)
} }
% endif % endif
% if product == "gecko": % if product == "gecko":
@ -950,7 +948,7 @@ impl ToCss for PropertyDeclaration {
let id = structs::${helpers.to_nscsspropertyid(property.ident)}; let id = structs::${helpers.to_nscsspropertyid(property.ident)};
let enabled = unsafe { bindings::Gecko_PropertyId_IsPrefEnabled(id) }; let enabled = unsafe { bindings::Gecko_PropertyId_IsPrefEnabled(id) };
if !enabled { if !enabled {
return PropertyDeclarationParseResult::ExperimentalProperty return Err(PropertyDeclarationParseError::ExperimentalProperty)
} }
} }
% endif % endif
@ -1060,19 +1058,19 @@ impl PropertyDeclaration {
pub fn parse(id: PropertyId, context: &ParserContext, input: &mut Parser, pub fn parse(id: PropertyId, context: &ParserContext, input: &mut Parser,
result_list: &mut Vec<(PropertyDeclaration, Importance)>, result_list: &mut Vec<(PropertyDeclaration, Importance)>,
in_keyframe_block: bool) in_keyframe_block: bool)
-> PropertyDeclarationParseResult { -> Result<(), PropertyDeclarationParseError> {
match id { match id {
PropertyId::Custom(name) => { PropertyId::Custom(name) => {
let value = match input.try(|i| CSSWideKeyword::parse(context, i)) { let value = match input.try(|i| CSSWideKeyword::parse(context, i)) {
Ok(keyword) => DeclaredValue::CSSWideKeyword(keyword), Ok(keyword) => DeclaredValue::CSSWideKeyword(keyword),
Err(()) => match ::custom_properties::SpecifiedValue::parse(context, input) { Err(()) => match ::custom_properties::SpecifiedValue::parse(context, input) {
Ok(value) => DeclaredValue::Value(value), Ok(value) => DeclaredValue::Value(value),
Err(()) => return PropertyDeclarationParseResult::InvalidValue, Err(()) => return Err(PropertyDeclarationParseError::InvalidValue),
} }
}; };
result_list.push((PropertyDeclaration::Custom(name, value), result_list.push((PropertyDeclaration::Custom(name, value),
Importance::Normal)); Importance::Normal));
return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration; return Ok(());
} }
PropertyId::Longhand(id) => match id { PropertyId::Longhand(id) => match id {
% for property in data.longhands: % for property in data.longhands:
@ -1080,12 +1078,12 @@ impl PropertyDeclaration {
% if not property.derived_from: % if not property.derived_from:
% if not property.allowed_in_keyframe_block: % if not property.allowed_in_keyframe_block:
if in_keyframe_block { if in_keyframe_block {
return PropertyDeclarationParseResult::AnimationPropertyInKeyframeBlock return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock)
} }
% endif % endif
% if property.internal: % if property.internal:
if context.stylesheet_origin != Origin::UserAgent { if context.stylesheet_origin != Origin::UserAgent {
return PropertyDeclarationParseResult::UnknownProperty return Err(PropertyDeclarationParseError::UnknownProperty)
} }
% endif % endif
@ -1095,12 +1093,12 @@ impl PropertyDeclaration {
Ok(value) => { Ok(value) => {
result_list.push((PropertyDeclaration::${property.camel_case}(value), result_list.push((PropertyDeclaration::${property.camel_case}(value),
Importance::Normal)); Importance::Normal));
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration Ok(())
}, },
Err(()) => PropertyDeclarationParseResult::InvalidValue, Err(()) => Err(PropertyDeclarationParseError::InvalidValue),
} }
% else: % else:
PropertyDeclarationParseResult::UnknownProperty Err(PropertyDeclarationParseError::UnknownProperty)
% endif % endif
} }
% endfor % endfor
@ -1110,12 +1108,12 @@ impl PropertyDeclaration {
ShorthandId::${shorthand.camel_case} => { ShorthandId::${shorthand.camel_case} => {
% if not shorthand.allowed_in_keyframe_block: % if not shorthand.allowed_in_keyframe_block:
if in_keyframe_block { if in_keyframe_block {
return PropertyDeclarationParseResult::AnimationPropertyInKeyframeBlock return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock)
} }
% endif % endif
% if shorthand.internal: % if shorthand.internal:
if context.stylesheet_origin != Origin::UserAgent { if context.stylesheet_origin != Origin::UserAgent {
return PropertyDeclarationParseResult::UnknownProperty return Err(PropertyDeclarationParseError::UnknownProperty)
} }
% endif % endif
@ -1128,16 +1126,16 @@ impl PropertyDeclaration {
PropertyDeclaration::${sub_property.camel_case}( PropertyDeclaration::${sub_property.camel_case}(
DeclaredValue::CSSWideKeyword(keyword)), Importance::Normal)); DeclaredValue::CSSWideKeyword(keyword)), Importance::Normal));
% endfor % endfor
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration Ok(())
}, },
Err(()) => match shorthands::${shorthand.ident}::parse(context, input) { Err(()) => match shorthands::${shorthand.ident}::parse(context, input) {
Ok(parsed) => { Ok(parsed) => {
parsed.expand(|declaration| { parsed.expand(|declaration| {
result_list.push((declaration, Importance::Normal)) result_list.push((declaration, Importance::Normal))
}); });
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration Ok(())
} }
Err(()) => PropertyDeclarationParseResult::InvalidValue, Err(()) => Err(PropertyDeclarationParseError::InvalidValue),
} }
} }
} }

View file

@ -205,7 +205,6 @@ impl Declaration {
/// ///
/// https://drafts.csswg.org/css-conditional-3/#support-definition /// https://drafts.csswg.org/css-conditional-3/#support-definition
pub fn eval(&self, cx: &ParserContext) -> bool { pub fn eval(&self, cx: &ParserContext) -> bool {
use properties::PropertyDeclarationParseResult::*;
let id = if let Ok(id) = PropertyId::parse((&*self.prop).into()) { let id = if let Ok(id) = PropertyId::parse((&*self.prop).into()) {
id id
} else { } else {
@ -219,13 +218,6 @@ impl Declaration {
if !input.is_exhausted() { if !input.is_exhausted() {
return false; return false;
} }
match res { res.is_ok()
UnknownProperty => false,
ExperimentalProperty => false, // only happens for experimental props
// that haven't been enabled
InvalidValue => false,
AnimationPropertyInKeyframeBlock => unreachable!(),
ValidOrIgnoredDeclaration => true,
}
} }
} }

View file

@ -68,7 +68,7 @@ use style::keyframes::KeyframesStepValue;
use style::parallel; use style::parallel;
use style::parser::{ParserContext, ParserContextExtraData}; use style::parser::{ParserContext, ParserContextExtraData};
use style::properties::{ComputedValues, Importance, PropertyDeclaration}; use style::properties::{ComputedValues, Importance, PropertyDeclaration};
use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId}; use style::properties::{PropertyDeclarationBlock, PropertyId};
use style::properties::animated_properties::{AnimationValue, Interpolate, TransitionProperty}; use style::properties::animated_properties::{AnimationValue, Interpolate, TransitionProperty};
use style::properties::parse_one_declaration; use style::properties::parse_one_declaration;
use style::restyle_hints::{self, RestyleHint}; use style::restyle_hints::{self, RestyleHint};
@ -714,10 +714,11 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const
extra_data); extra_data);
let mut results = vec![]; let mut results = vec![];
match PropertyDeclaration::parse(id, &context, &mut Parser::new(value), let result = PropertyDeclaration::parse(
&mut results, false) { id, &context, &mut Parser::new(value), &mut results, false
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {}, );
_ => return RawServoDeclarationBlockStrong::null(), if result.is_err() {
return RawServoDeclarationBlockStrong::null()
} }
Arc::new(RwLock::new(PropertyDeclarationBlock { Arc::new(RwLock::new(PropertyDeclarationBlock {