Fix handling of potentially overlapping selectors in property sheets

This commit is contained in:
Max Brunsfeld 2019-07-22 11:00:57 -07:00
parent 443ac1c1e5
commit a21d355ade
2 changed files with 65 additions and 20 deletions

View file

@ -407,24 +407,68 @@ impl<'a> Builder<'a> {
left: &PropertyTransitionJSON,
right: &PropertyTransitionJSON,
) -> Option<PropertyTransitionJSON> {
// If one transition is based on the node's type and the other
// is based on its field name, then create a combined transition
// wiht *both* criteria.
if let (Some(left_field), None) = (&left.field, &left.kind) {
if right.field.is_none() {
let mut result = right.clone();
result.field = Some(left_field.clone());
return Some(result);
let mut left_contributes = false;
let mut right_contributes = false;
let mut result = left.clone();
if let Some(left_kind) = &left.kind {
if let Some(right_kind) = &right.kind {
if left_kind != right_kind || left.named != right.named {
return None;
}
} else {
left_contributes = true;
}
} else if let Some(right_kind) = &right.kind {
result.kind = Some(right_kind.clone());
result.named = right.named;
right_contributes = true;
}
if let (Some(right_field), None) = (&right.field, &right.kind) {
if left.field.is_none() {
let mut result = left.clone();
result.field = Some(right_field.clone());
return Some(result);
if let Some(left_field) = &left.field {
if let Some(right_field) = &right.field {
if left_field != right_field {
return None;
}
} else {
left_contributes = true;
}
} else if let Some(right_field) = &right.field {
result.field = Some(right_field.clone());
right_contributes = true;
}
if let Some(left_text) = &left.text {
if let Some(right_text) = &right.text {
if left_text != right_text {
return None;
}
} else {
left_contributes = true;
}
} else if let Some(right_text) = &right.text {
result.text = Some(right_text.clone());
right_contributes = true;
}
if let Some(left_index) = &left.index {
if let Some(right_index) = &right.index {
if left_index != right_index {
return None;
}
} else {
left_contributes = true;
}
} else if let Some(right_index) = &right.index {
result.index = Some(right_index.clone());
right_contributes = true;
}
if left_contributes && right_contributes {
Some(result)
} else {
None
}
return None;
}
fn remove_duplicate_states(&mut self) {

View file

@ -2,9 +2,9 @@ use super::helpers::fixtures::get_language;
use crate::generate::properties;
use serde_derive::Deserialize;
use serde_json;
use tree_sitter::{Parser, PropertySheet};
use std::collections::HashSet;
use std::collections::HashSet;
use tree_sitter::{Parser, PropertySheet};
#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
struct Properties {
a: Option<String>,
@ -31,7 +31,7 @@ fn test_walk_with_properties_with_nth_child() {
a: z;
}
",
)
),
)
.unwrap();
@ -106,7 +106,7 @@ fn test_walk_with_properties_with_regexes() {
a: x;
}
",
)
),
)
.unwrap();
@ -195,7 +195,7 @@ fn test_walk_with_properties_based_on_fields() {
a: w;
}
",
)
),
)
.unwrap();
@ -260,5 +260,6 @@ fn test_walk_with_properties_based_on_fields() {
}
fn generate_property_sheet_string(path: &str, css: &str) -> String {
serde_json::to_string(&properties::generate_property_sheet(path, css, &HashSet::new()).unwrap()).unwrap()
serde_json::to_string(&properties::generate_property_sheet(path, css, &HashSet::new()).unwrap())
.unwrap()
}