From def1e1e91ae8c35149ca24bf0655903c6a861dab Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 16 Jul 2019 17:58:18 -0700 Subject: [PATCH] Reduce bloat in generated property sheet JSON files --- cli/src/properties.rs | 8 ++++- lib/binding_rust/lib.rs | 67 +++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/cli/src/properties.rs b/cli/src/properties.rs index 86d87592..0b424938 100644 --- a/cli/src/properties.rs +++ b/cli/src/properties.rs @@ -162,12 +162,17 @@ impl Builder { } fn populate_state(&mut self, item_set: ItemSet, state_id: StateId) { + let is_start_state = state_id == 0; let mut transitions: HashMap = HashMap::new(); let mut selector_matches = Vec::new(); - // First, compute all of the possible state transition predicates for + // First, compute all of the possible state transition conditions for // this state, and all of the rules that are currently matching. for item in &item_set { + if !is_start_state && item.step_id == 0 { + continue; + } + let rule = &self.rules[item.rule_id as usize]; let selector = &rule.selectors[item.selector_id as usize]; let next_step = selector.0.get(item.step_id as usize); @@ -1265,6 +1270,7 @@ mod tests { state_id = state .transitions .iter() + .chain(sheet.states[0].transitions.iter()) .find(|transition| { transition.kind.as_ref().map_or(true, |k| k == kind) && transition.named.map_or(true, |n| n == is_named) diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index f6ee0632..ff2cf5d5 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -88,7 +88,7 @@ pub struct PropertySheet

> { text_regexes: Vec, } -#[derive(Debug, Deserialize, Serialize, Hash, PartialEq, Eq)] +#[derive(Clone, Debug, Deserialize, Serialize, Hash, PartialEq, Eq)] pub struct PropertyTransitionJSON { #[serde(rename = "type")] #[serde(skip_serializing_if = "Option::is_none")] @@ -773,50 +773,57 @@ impl<'a, P> TreePropertyCursor<'a, P> { } fn next_state(&self, node_child_index: usize) -> usize { - let state = self.current_state(); - let node_field_id = self.cursor.field_id(); - let node_kind_id = self.cursor.node().kind_id(); - let transitions = node_field_id - .and_then(|field_id| state.field_transitions.get(&field_id)) - .or_else(|| state.kind_transitions.get(&node_kind_id)); + let current_state = self.current_state(); - if let Some(transitions) = transitions { - for transition in transitions.iter() { - if transition - .node_kind_id - .map_or(false, |id| id != node_kind_id) - { - continue; - } + for state in [current_state, self.default_state()].iter() { + let node_field_id = self.cursor.field_id(); + let node_kind_id = self.cursor.node().kind_id(); + let transitions = node_field_id + .and_then(|field_id| state.field_transitions.get(&field_id)) + .or_else(|| state.kind_transitions.get(&node_kind_id)); - if let Some(text_regex_index) = transition.text_regex_index { - let node = self.cursor.node(); - let text = &self.source[node.start_byte()..node.end_byte()]; - if let Ok(text) = str::from_utf8(text) { - if !self.property_sheet.text_regexes[text_regex_index as usize] - .is_match(text) - { + if let Some(transitions) = transitions { + for transition in transitions.iter() { + if transition + .node_kind_id + .map_or(false, |id| id != node_kind_id) + { + continue; + } + + if let Some(text_regex_index) = transition.text_regex_index { + let node = self.cursor.node(); + let text = &self.source[node.start_byte()..node.end_byte()]; + if let Ok(text) = str::from_utf8(text) { + if !self.property_sheet.text_regexes[text_regex_index as usize] + .is_match(text) + { + continue; + } + } + } + + if let Some(child_index) = transition.child_index { + if child_index != node_child_index as u16 { continue; } } - } - if let Some(child_index) = transition.child_index { - if child_index != node_child_index as u16 { - continue; - } + return transition.state_id as usize; } - - return transition.state_id as usize; } } - state.default_next_state_id + current_state.default_next_state_id } fn current_state(&self) -> &PropertyState { &self.property_sheet.states[*self.state_stack.last().unwrap()] } + + fn default_state(&self) -> &PropertyState { + &self.property_sheet.states.first().unwrap() + } } impl Point {