mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Simplify invalid custom property handling.
It's a bit useless to keep a set of invalid properties if we're going to use them just to reject lookups into another key. This makes it more consistent with the cascade / no-references code, and should not change behavior. Differential Revision: https://phabricator.services.mozilla.com/D9632
This commit is contained in:
parent
b7da1bac88
commit
99f9d84555
1 changed files with 12 additions and 61 deletions
|
@ -230,18 +230,6 @@ where
|
||||||
self.index.remove(index);
|
self.index.remove(index);
|
||||||
self.values.remove(key)
|
self.values.remove(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_set<S>(&mut self, set: &::hash::HashSet<K, S>)
|
|
||||||
where
|
|
||||||
S: ::std::hash::BuildHasher,
|
|
||||||
{
|
|
||||||
if set.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.index.retain(|key| !set.contains(key));
|
|
||||||
self.values.retain(|key, _| !set.contains(key));
|
|
||||||
debug_assert_eq!(self.values.len(), self.index.len());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator for OrderedMap.
|
/// An iterator for OrderedMap.
|
||||||
|
@ -642,11 +630,9 @@ impl<'a> CustomPropertiesBuilder<'a> {
|
||||||
// environment variable here, perform substitution here instead
|
// environment variable here, perform substitution here instead
|
||||||
// of forcing a full traversal in `substitute_all` afterwards.
|
// of forcing a full traversal in `substitute_all` afterwards.
|
||||||
let value = if !has_references && unparsed_value.references_environment {
|
let value = if !has_references && unparsed_value.references_environment {
|
||||||
let invalid = Default::default(); // Irrelevant, since there are no references.
|
|
||||||
let result = substitute_references_in_value(
|
let result = substitute_references_in_value(
|
||||||
unparsed_value,
|
unparsed_value,
|
||||||
&map,
|
&map,
|
||||||
&invalid,
|
|
||||||
&self.environment,
|
&self.environment,
|
||||||
);
|
);
|
||||||
match result {
|
match result {
|
||||||
|
@ -735,18 +721,6 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
// listed in
|
// listed in
|
||||||
// https://en.wikipedia.org/w/index.php?
|
// https://en.wikipedia.org/w/index.php?
|
||||||
// title=Tarjan%27s_strongly_connected_components_algorithm&oldid=801728495
|
// title=Tarjan%27s_strongly_connected_components_algorithm&oldid=801728495
|
||||||
//
|
|
||||||
// FIXME This function currently does at least one addref to names
|
|
||||||
// for each variable regardless whether it has reference. Each
|
|
||||||
// variable with any reference would have an additional addref.
|
|
||||||
// There is another addref for each reference.
|
|
||||||
// Strictly speaking, these addrefs are not necessary, because we
|
|
||||||
// don't add/remove entry from custom properties map, and thus keys
|
|
||||||
// should be alive in the whole process until we start removing
|
|
||||||
// invalids. However, there is no safe way for us to prove this to
|
|
||||||
// the compiler. We may be able to fix this issue at some point if
|
|
||||||
// the standard library can provide some kind of hashmap wrapper
|
|
||||||
// with frozen keys.
|
|
||||||
|
|
||||||
/// Struct recording necessary information for each variable.
|
/// Struct recording necessary information for each variable.
|
||||||
struct VarInfo {
|
struct VarInfo {
|
||||||
|
@ -775,8 +749,6 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
/// all unfinished strong connected components.
|
/// all unfinished strong connected components.
|
||||||
stack: SmallVec<[usize; 5]>,
|
stack: SmallVec<[usize; 5]>,
|
||||||
map: &'a mut CustomPropertiesMap,
|
map: &'a mut CustomPropertiesMap,
|
||||||
/// The set of invalid custom properties.
|
|
||||||
invalid: &'a mut PrecomputedHashSet<Name>,
|
|
||||||
/// The environment to substitute `env()` variables.
|
/// The environment to substitute `env()` variables.
|
||||||
environment: &'a CssEnvironment,
|
environment: &'a CssEnvironment,
|
||||||
}
|
}
|
||||||
|
@ -790,9 +762,9 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
/// in one of the following states:
|
/// in one of the following states:
|
||||||
/// * It is still in context.stack, which means it is part of an
|
/// * It is still in context.stack, which means it is part of an
|
||||||
/// potentially incomplete dependency circle.
|
/// potentially incomplete dependency circle.
|
||||||
/// * It has been added into the invalid set. It can be either that
|
/// * It has been removed from the map. It can be either that the
|
||||||
/// the substitution failed, or it is inside a dependency circle.
|
/// substitution failed, or it is inside a dependency circle.
|
||||||
/// When this function put a variable into the invalid set because
|
/// When this function removes a variable from the map because
|
||||||
/// of dependency circle, it would put all variables in the same
|
/// of dependency circle, it would put all variables in the same
|
||||||
/// strong connected component to the set together.
|
/// strong connected component to the set together.
|
||||||
/// * It doesn't have any reference, because either this variable
|
/// * It doesn't have any reference, because either this variable
|
||||||
|
@ -813,11 +785,6 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This variable has already been resolved.
|
|
||||||
if context.invalid.contains(&name) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whether this variable has been visited in this traversal.
|
// Whether this variable has been visited in this traversal.
|
||||||
let key;
|
let key;
|
||||||
match context.index_map.entry(name) {
|
match context.index_map.entry(name) {
|
||||||
|
@ -875,8 +842,9 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
if lowlink != index {
|
if lowlink != index {
|
||||||
// This variable is in a loop, but it is not the root of
|
// This variable is in a loop, but it is not the root of
|
||||||
// this strong connected component. We simply return for
|
// this strong connected component. We simply return for
|
||||||
// now, and the root would add it into the invalid set.
|
// now, and the root would remove it from the map.
|
||||||
// This cannot be added into the invalid set here, because
|
//
|
||||||
|
// This cannot be removed from the map here, because
|
||||||
// otherwise the shortcut check at the beginning of this
|
// otherwise the shortcut check at the beginning of this
|
||||||
// function would return the wrong value.
|
// function would return the wrong value.
|
||||||
return Some(index);
|
return Some(index);
|
||||||
|
@ -903,15 +871,14 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Anything here is in a loop which can traverse to the
|
// Anything here is in a loop which can traverse to the
|
||||||
// variable we are handling, so we should add it into
|
// variable we are handling, so remove it from the map, it's invalid
|
||||||
// the invalid set. We should never visit the variable
|
// at computed-value time.
|
||||||
// again so it's safe to just take the name away.
|
context.map.remove(&var_name);
|
||||||
context.invalid.insert(var_name);
|
|
||||||
in_loop = true;
|
in_loop = true;
|
||||||
}
|
}
|
||||||
if in_loop {
|
if in_loop {
|
||||||
// This variable is in loop. Resolve to invalid.
|
// This variable is in loop. Resolve to invalid.
|
||||||
context.invalid.insert(name);
|
context.map.remove(&name);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +888,6 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
let result = substitute_references_in_value(
|
let result = substitute_references_in_value(
|
||||||
&value,
|
&value,
|
||||||
&context.map,
|
&context.map,
|
||||||
&context.invalid,
|
|
||||||
&context.environment,
|
&context.environment,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -930,7 +896,7 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
context.map.insert(name, Arc::new(computed_value));
|
context.map.insert(name, Arc::new(computed_value));
|
||||||
},
|
},
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
context.invalid.insert(name);
|
context.map.remove(&name);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,7 +907,6 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
// We have to clone the names so that we can mutably borrow the map
|
// We have to clone the names so that we can mutably borrow the map
|
||||||
// in the context we create for traversal.
|
// in the context we create for traversal.
|
||||||
let names = custom_properties_map.index.clone();
|
let names = custom_properties_map.index.clone();
|
||||||
let mut invalid = PrecomputedHashSet::default();
|
|
||||||
for name in names.into_iter() {
|
for name in names.into_iter() {
|
||||||
let mut context = Context {
|
let mut context = Context {
|
||||||
count: 0,
|
count: 0,
|
||||||
|
@ -949,20 +914,16 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
stack: SmallVec::new(),
|
stack: SmallVec::new(),
|
||||||
var_info: SmallVec::new(),
|
var_info: SmallVec::new(),
|
||||||
map: custom_properties_map,
|
map: custom_properties_map,
|
||||||
invalid: &mut invalid,
|
|
||||||
environment,
|
environment,
|
||||||
};
|
};
|
||||||
traverse(name, &mut context);
|
traverse(name, &mut context);
|
||||||
}
|
}
|
||||||
|
|
||||||
custom_properties_map.remove_set(&invalid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace `var()` and `env()` functions in a pre-existing variable value.
|
/// Replace `var()` and `env()` functions in a pre-existing variable value.
|
||||||
fn substitute_references_in_value<'i>(
|
fn substitute_references_in_value<'i>(
|
||||||
value: &'i VariableValue,
|
value: &'i VariableValue,
|
||||||
custom_properties: &CustomPropertiesMap,
|
custom_properties: &CustomPropertiesMap,
|
||||||
invalid_custom_properties: &PrecomputedHashSet<Name>,
|
|
||||||
environment: &CssEnvironment,
|
environment: &CssEnvironment,
|
||||||
) -> Result<ComputedValue, ParseError<'i>> {
|
) -> Result<ComputedValue, ParseError<'i>> {
|
||||||
debug_assert!(!value.references.is_empty() || value.references_environment);
|
debug_assert!(!value.references.is_empty() || value.references_environment);
|
||||||
|
@ -977,7 +938,6 @@ fn substitute_references_in_value<'i>(
|
||||||
&mut position,
|
&mut position,
|
||||||
&mut computed_value,
|
&mut computed_value,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
invalid_custom_properties,
|
|
||||||
environment,
|
environment,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1000,7 +960,6 @@ fn substitute_block<'i, 't>(
|
||||||
position: &mut (SourcePosition, TokenSerializationType),
|
position: &mut (SourcePosition, TokenSerializationType),
|
||||||
partial_computed_value: &mut ComputedValue,
|
partial_computed_value: &mut ComputedValue,
|
||||||
custom_properties: &CustomPropertiesMap,
|
custom_properties: &CustomPropertiesMap,
|
||||||
invalid_custom_properties: &PrecomputedHashSet<Name>,
|
|
||||||
env: &CssEnvironment,
|
env: &CssEnvironment,
|
||||||
) -> Result<TokenSerializationType, ParseError<'i>> {
|
) -> Result<TokenSerializationType, ParseError<'i>> {
|
||||||
let mut last_token_type = TokenSerializationType::nothing();
|
let mut last_token_type = TokenSerializationType::nothing();
|
||||||
|
@ -1050,11 +1009,7 @@ fn substitute_block<'i, 't>(
|
||||||
let value = if is_env {
|
let value = if is_env {
|
||||||
env.get(&name)
|
env.get(&name)
|
||||||
} else {
|
} else {
|
||||||
if invalid_custom_properties.contains(&name) {
|
custom_properties.get(&name).map(|v| &**v)
|
||||||
None
|
|
||||||
} else {
|
|
||||||
custom_properties.get(&name).map(|v| &**v)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(v) = value {
|
if let Some(v) = value {
|
||||||
|
@ -1079,7 +1034,6 @@ fn substitute_block<'i, 't>(
|
||||||
&mut position,
|
&mut position,
|
||||||
partial_computed_value,
|
partial_computed_value,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
invalid_custom_properties,
|
|
||||||
env,
|
env,
|
||||||
)?;
|
)?;
|
||||||
partial_computed_value.push_from(position, input, last_token_type);
|
partial_computed_value.push_from(position, input, last_token_type);
|
||||||
|
@ -1098,7 +1052,6 @@ fn substitute_block<'i, 't>(
|
||||||
position,
|
position,
|
||||||
partial_computed_value,
|
partial_computed_value,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
invalid_custom_properties,
|
|
||||||
env,
|
env,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
@ -1131,7 +1084,6 @@ pub fn substitute<'i>(
|
||||||
let mut input = ParserInput::new(input);
|
let mut input = ParserInput::new(input);
|
||||||
let mut input = Parser::new(&mut input);
|
let mut input = Parser::new(&mut input);
|
||||||
let mut position = (input.position(), first_token_type);
|
let mut position = (input.position(), first_token_type);
|
||||||
let invalid = PrecomputedHashSet::default();
|
|
||||||
let empty_map = CustomPropertiesMap::new();
|
let empty_map = CustomPropertiesMap::new();
|
||||||
let custom_properties = match computed_values_map {
|
let custom_properties = match computed_values_map {
|
||||||
Some(m) => &**m,
|
Some(m) => &**m,
|
||||||
|
@ -1142,7 +1094,6 @@ pub fn substitute<'i>(
|
||||||
&mut position,
|
&mut position,
|
||||||
&mut substituted,
|
&mut substituted,
|
||||||
&custom_properties,
|
&custom_properties,
|
||||||
&invalid,
|
|
||||||
env,
|
env,
|
||||||
)?;
|
)?;
|
||||||
substituted.push_from(position, &input, last_token_type);
|
substituted.push_from(position, &input, last_token_type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue