fork of https://github.com/tree-sitter/tree-sitter-graph

Do not store used_captures in the store, where they don't belong

Changed files
+68 -49
src
+68 -49
src/checker.rs
··· 105 105 106 106 /// Checker context 107 107 struct CheckContext<'a> { 108 - globals: &'a dyn Variables<ExpressionResult>, 108 + globals: &'a dyn Variables<VariableResult>, 109 109 file_query: &'a Query, 110 110 stanza_index: usize, 111 111 stanza_query: &'a Query, 112 - locals: &'a mut dyn MutVariables<ExpressionResult>, 112 + locals: &'a mut dyn MutVariables<VariableResult>, 113 + } 114 + 115 + #[derive(Clone, Debug)] 116 + struct VariableResult { 117 + is_local: bool, 118 + quantifier: CaptureQuantifier, 113 119 } 114 120 115 121 //----------------------------------------------------------------------------- ··· 122 128 globals 123 129 .add( 124 130 global.name.clone(), 125 - ExpressionResult { 131 + VariableResult { 126 132 quantifier: global.quantifier, 127 133 is_local: true, 128 - used_captures: HashSet::new(), 129 134 }, 130 135 false, 131 136 ) ··· 150 155 impl ast::Stanza { 151 156 fn check( 152 157 &mut self, 153 - globals: &dyn Variables<ExpressionResult>, 158 + globals: &dyn Variables<VariableResult>, 154 159 file_query: &Query, 155 160 stanza_index: usize, 156 161 ) -> Result<(), CheckError> { ··· 232 237 let mut used_captures = HashSet::new(); 233 238 let value = self.value.check(ctx)?; 234 239 used_captures.extend(value.used_captures.iter().cloned()); 235 - let var_result = self.variable.check_add(ctx, value, false)?; 240 + let var_result = self.variable.check_add(ctx, value.into(), false)?; 236 241 used_captures.extend(var_result.used_captures); 237 242 Ok(StatementResult { used_captures }) 238 243 } ··· 243 248 let mut used_captures = HashSet::new(); 244 249 let value = self.value.check(ctx)?; 245 250 used_captures.extend(value.used_captures.iter().cloned()); 246 - let var_result = self.variable.check_add(ctx, value, true)?; 251 + let var_result = self.variable.check_add(ctx, value.into(), true)?; 247 252 used_captures.extend(var_result.used_captures); 248 253 Ok(StatementResult { used_captures }) 249 254 } ··· 254 259 let mut used_captures = HashSet::new(); 255 260 let value = self.value.check(ctx)?; 256 261 used_captures.extend(value.used_captures.iter().cloned()); 257 - let var_result = self.variable.check_set(ctx, value)?; 262 + let var_result = self.variable.check_set(ctx, value.into())?; 258 263 used_captures.extend(var_result.used_captures); 259 264 Ok(StatementResult { used_captures }) 260 265 } ··· 264 269 fn check(&mut self, ctx: &mut CheckContext) -> Result<StatementResult, CheckError> { 265 270 let node_result = self.node.check_add( 266 271 ctx, 267 - ExpressionResult { 272 + VariableResult { 268 273 is_local: true, 269 274 quantifier: One, 270 - used_captures: HashSet::new(), 271 275 }, 272 276 false, 273 277 )?; ··· 445 449 }; 446 450 let var_result = self 447 451 .variable 448 - .check_add(&mut loop_ctx, value_result, false)?; 452 + .check_add(&mut loop_ctx, value_result.into(), false)?; 449 453 used_captures.extend(var_result.used_captures); 450 454 451 455 for statement in &mut self.statements { ··· 577 581 }; 578 582 let var_result = self 579 583 .variable 580 - .check_add(&mut loop_ctx, value_result, false)?; 584 + .check_add(&mut loop_ctx, value_result.into(), false)?; 581 585 used_captures.extend(var_result.used_captures); 582 586 583 587 let element_result = self.element.check(&mut loop_ctx)?; ··· 614 618 }; 615 619 let var_result = self 616 620 .variable 617 - .check_add(&mut loop_ctx, value_result, false)?; 621 + .check_add(&mut loop_ctx, value_result.into(), false)?; 618 622 used_captures.extend(var_result.used_captures); 619 623 620 624 let element_result = self.element.check(&mut loop_ctx)?; ··· 680 684 //----------------------------------------------------------------------------- 681 685 // Variables 682 686 683 - #[derive(Clone, Debug)] 684 - struct VariableResult { 685 - used_captures: HashSet<Identifier>, 686 - } 687 - 688 687 impl ast::Variable { 689 688 fn check_add( 690 689 &mut self, 691 690 ctx: &mut CheckContext, 692 - value: ExpressionResult, 691 + value: VariableResult, 693 692 mutable: bool, 694 - ) -> Result<VariableResult, CheckError> { 693 + ) -> Result<StatementResult, CheckError> { 695 694 match self { 696 695 Self::Unscoped(v) => v.check_add(ctx, value, mutable), 697 696 Self::Scoped(v) => v.check_add(ctx, value, mutable), ··· 701 700 fn check_set( 702 701 &mut self, 703 702 ctx: &mut CheckContext, 704 - value: ExpressionResult, 705 - ) -> Result<VariableResult, CheckError> { 703 + value: VariableResult, 704 + ) -> Result<StatementResult, CheckError> { 706 705 match self { 707 706 Self::Unscoped(v) => v.check_set(ctx, value), 708 707 Self::Scoped(v) => v.check_set(ctx, value), ··· 721 720 fn check_add( 722 721 &mut self, 723 722 ctx: &mut CheckContext, 724 - value: ExpressionResult, 723 + value: VariableResult, 725 724 mutable: bool, 726 - ) -> Result<VariableResult, CheckError> { 725 + ) -> Result<StatementResult, CheckError> { 727 726 if ctx.globals.get(&self.name).is_some() { 728 727 return Err(CheckError::CannotHideGlobalVariable( 729 728 self.name.as_str().to_string(), ··· 738 737 if mutable { 739 738 value.is_local = false; 740 739 } 741 - let used_captures = value.used_captures.clone(); 742 - value.used_captures.clear(); // prevent used captures from escaping 743 - // we may want to separate quantifier/is_local from 744 - // the used_captures and only store the former in the 745 - // future for a cleaner solution 746 740 ctx.locals 747 741 .add(self.name.clone(), value, mutable) 748 742 .map_err(|e| CheckError::Variable(e, format!("{}", self.name), self.location))?; 749 - Ok(VariableResult { used_captures }) 743 + Ok(StatementResult { 744 + used_captures: HashSet::default(), 745 + }) 750 746 } 751 747 752 748 fn check_set( 753 749 &mut self, 754 750 ctx: &mut CheckContext, 755 - value: ExpressionResult, 756 - ) -> Result<VariableResult, CheckError> { 751 + value: VariableResult, 752 + ) -> Result<StatementResult, CheckError> { 757 753 if ctx.globals.get(&self.name).is_some() { 758 754 return Err(CheckError::CannotSetGlobalVariable( 759 755 self.name.as_str().to_string(), ··· 766 762 // Since we process all statement in order, we don't have info on later 767 763 // assignments, and can assume non-local to be sound. 768 764 value.is_local = false; 769 - let used_captures = value.used_captures.clone(); 770 - value.used_captures.clear(); // prevent used captures from escaping 771 - // we may want to separate quantifier/is_local from 772 - // the used_captures and only store the former in the 773 - // future for a cleaner solution 774 765 ctx.locals 775 766 .set(self.name.clone(), value) 776 767 .map_err(|e| CheckError::Variable(e, format!("{}", self.name), self.location))?; 777 - Ok(VariableResult { used_captures }) 768 + Ok(StatementResult { 769 + used_captures: HashSet::default(), 770 + }) 778 771 } 779 772 780 773 fn check_get(&mut self, ctx: &mut CheckContext) -> Result<ExpressionResult, CheckError> { ··· 783 776 } else { 784 777 ctx.locals.get(&self.name) 785 778 } 786 - .cloned() 779 + .map(|value| value.into()) 787 780 .ok_or_else(|| CheckError::UndefinedVariable(self.name.as_str().to_string(), self.location)) 788 781 } 789 782 } ··· 792 785 fn check_add( 793 786 &mut self, 794 787 ctx: &mut CheckContext, 795 - _value: ExpressionResult, 788 + _value: VariableResult, 796 789 _mutable: bool, 797 - ) -> Result<VariableResult, CheckError> { 790 + ) -> Result<StatementResult, CheckError> { 798 791 let scope_result = self.scope.check(ctx)?; 799 - Ok(VariableResult { 800 - used_captures: scope_result.used_captures, 801 - }) 792 + Ok(scope_result.into()) 802 793 } 803 794 804 795 fn check_set( 805 796 &mut self, 806 797 ctx: &mut CheckContext, 807 - _value: ExpressionResult, 808 - ) -> Result<VariableResult, CheckError> { 798 + _value: VariableResult, 799 + ) -> Result<StatementResult, CheckError> { 809 800 let scope_result = self.scope.check(ctx)?; 810 - Ok(VariableResult { 811 - used_captures: scope_result.used_captures, 812 - }) 801 + Ok(scope_result.into()) 813 802 } 814 803 815 804 fn check_get(&mut self, ctx: &mut CheckContext) -> Result<ExpressionResult, CheckError> { ··· 838 827 }) 839 828 } 840 829 } 830 + 831 + //----------------------------------------------------------------------------- 832 + // Result Conversions 833 + 834 + impl Into<StatementResult> for ExpressionResult { 835 + fn into(self) -> StatementResult { 836 + StatementResult { 837 + used_captures: self.used_captures, 838 + } 839 + } 840 + } 841 + 842 + impl Into<ExpressionResult> for &VariableResult { 843 + fn into(self) -> ExpressionResult { 844 + ExpressionResult { 845 + is_local: self.is_local, 846 + quantifier: self.quantifier, 847 + used_captures: HashSet::default(), 848 + } 849 + } 850 + } 851 + 852 + impl Into<VariableResult> for ExpressionResult { 853 + fn into(self) -> VariableResult { 854 + VariableResult { 855 + is_local: self.is_local, 856 + quantifier: self.quantifier, 857 + } 858 + } 859 + }