Classify variables relative to a byte range `[start, end)`. This is the primary query for Extract Function: it determines which variables become parameters, return values, or locals.
(&self, start: u32, end: u32)
| 250 | /// This is the primary query for Extract Function: it determines |
| 251 | /// which variables become parameters, return values, or locals. |
| 252 | pub(crate) fn classify_range(&self, start: u32, end: u32) -> RangeClassification { |
| 253 | let frame = match self.enclosing_frame_for_range(start, end) { |
| 254 | Some(f) => f, |
| 255 | None => return RangeClassification::default(), |
| 256 | }; |
| 257 | |
| 258 | // Collect all unique variable names accessed within the range |
| 259 | // (excluding nested frames and pseudo-variables). |
| 260 | let mut var_names: Vec<String> = Vec::new(); |
| 261 | for access in &self.accesses { |
| 262 | if access.offset >= start |
| 263 | && access.offset < end |
| 264 | && !var_names.contains(&access.name) |
| 265 | && access.name != "$this" |
| 266 | && access.name != "self" |
| 267 | && access.name != "static" |
| 268 | && access.name != "parent" |
| 269 | { |
| 270 | // Skip if inside a nested frame. |
| 271 | let in_nested = self.frames.iter().any(|f| { |
| 272 | f.start > frame.start |
| 273 | && f.end < frame.end |
| 274 | && access.offset >= f.start |
| 275 | && access.offset <= f.end |
| 276 | && f.kind != FrameKind::Catch |
| 277 | }); |
| 278 | if !in_nested { |
| 279 | var_names.push(access.name.clone()); |
| 280 | } |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | // Check for $this / self / static / parent usage in range. |
| 285 | let mut result = RangeClassification { |
| 286 | uses_this: self.accesses.iter().any(|a| { |
| 287 | a.offset >= start |
| 288 | && a.offset < end |
| 289 | && (a.name == "$this" |
| 290 | || a.name == "self" |
| 291 | || a.name == "static" |
| 292 | || a.name == "parent") |
| 293 | }), |
| 294 | ..Default::default() |
| 295 | }; |
| 296 | |
| 297 | for var_name in &var_names { |
| 298 | let frame_accesses = self.accesses_in_frame(var_name, frame); |
| 299 | |
| 300 | let has_write_before = frame_accesses.iter().any(|a| { |
| 301 | a.offset < start && matches!(a.kind, AccessKind::Write | AccessKind::ReadWrite) |
| 302 | }); |
| 303 | |
| 304 | let has_read_inside = frame_accesses.iter().any(|a| { |
| 305 | a.offset >= start |
| 306 | && a.offset < end |
| 307 | && matches!(a.kind, AccessKind::Read | AccessKind::ReadWrite) |
| 308 | }); |
| 309 |