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

Ensure all scoped variables are forced to uncover hidden errors

Changed files
+34 -23
src
execution
+1
src/execution/lazy.rs
··· 106 106 // make sure any unforced values are now forced, to surface any problems 107 107 // hidden by the fact that the values were unused 108 108 store.evaluate_all(&mut exec)?; 109 + scoped_store.evaluate_all(&mut exec)?; 109 110 110 111 Ok(()) 111 112 }
+33 -23
src/execution/lazy/store.rs
··· 140 140 name: &Identifier, 141 141 exec: &mut EvaluationContext, 142 142 ) -> Result<LazyValue, ExecutionError> { 143 - let values = match self.variables.get(name) { 143 + let cell = match self.variables.get(name) { 144 144 Some(v) => v, 145 145 None => { 146 146 return Err(ExecutionError::UndefinedScopedVariable(format!( ··· 149 149 ))); 150 150 } 151 151 }; 152 - match values.replace(ScopedValues::Forcing) { 152 + let values = cell.replace(ScopedValues::Forcing); 153 + let map = self.force(name, values, exec)?; 154 + let result = map 155 + .get(&scope) 156 + .ok_or(ExecutionError::UndefinedScopedVariable(format!( 157 + "{}.{}", 158 + scope, name, 159 + )))? 160 + .clone(); 161 + cell.replace(ScopedValues::Forced(map)); 162 + Ok(result) 163 + } 164 + 165 + pub(super) fn evaluate_all(&self, exec: &mut EvaluationContext) -> Result<(), ExecutionError> { 166 + for (name, cell) in &self.variables { 167 + let values = cell.replace(ScopedValues::Forcing); 168 + let map = self.force(name, values, exec)?; 169 + cell.replace(ScopedValues::Forced(map)); 170 + } 171 + Ok(()) 172 + } 173 + 174 + fn force( 175 + &self, 176 + name: &Identifier, 177 + values: ScopedValues, 178 + exec: &mut EvaluationContext, 179 + ) -> Result<HashMap<SyntaxNodeRef, LazyValue>, ExecutionError> { 180 + match values { 153 181 ScopedValues::Unforced(pairs) => { 154 182 let mut map = HashMap::new(); 155 183 let mut debug_infos = HashMap::new(); ··· 170 198 _ => {} 171 199 }; 172 200 } 173 - let result = map 174 - .get(&scope) 175 - .ok_or(ExecutionError::UndefinedScopedVariable(format!( 176 - "{}.{}", 177 - scope, name, 178 - )))? 179 - .clone(); 180 - values.replace(ScopedValues::Forced(map)); 181 - Ok(result) 201 + Ok(map) 182 202 } 183 203 ScopedValues::Forcing => Err(ExecutionError::RecursivelyDefinedScopedVariable( 184 - format!("_.{} requested on {}", name, scope), 204 + format!("_.{}", name), 185 205 )), 186 - ScopedValues::Forced(map) => { 187 - let result = map 188 - .get(&scope) 189 - .ok_or(ExecutionError::UndefinedScopedVariable(format!( 190 - "{}.{}", 191 - scope, name, 192 - )))? 193 - .clone(); 194 - values.replace(ScopedValues::Forced(map)); 195 - Ok(result) 196 - } 206 + ScopedValues::Forced(map) => Ok(map), 197 207 } 198 208 } 199 209 }