use crate::classstore::ClassStore; use crate::classfile::{ FieldInfo, MethodInfo }; // Iterator over all the fields of a class object including superclass fields pub struct ClassFieldIterator<'i> { field_index: usize, class_index: usize, class_store: &'i ClassStore, } impl <'i>ClassFieldIterator<'i> { pub fn new(class_index: usize, class_store: &'i ClassStore) -> Self { ClassFieldIterator { field_index: 0, class_index, class_store, } } } impl <'i> Iterator for ClassFieldIterator<'i>{ type Item = &'i FieldInfo; fn next(&mut self) -> Option { let mut class_file = self.class_store.class_file_from_idx(self.class_index).unwrap(); while class_file.has_super_class() && class_file.fields.len() == self.field_index { let super_class_name = class_file.get_super_class_name().unwrap(); let (super_class_file, super_class_index) = self.class_store.get_class(super_class_name).unwrap(); class_file = super_class_file; self.class_index = super_class_index; self.field_index = 0; } if class_file.fields.len() == self.field_index { return None; } else { let field_info = &class_file.fields[self.field_index]; self.field_index += 1; return Some(field_info); } } } pub struct CompatibleTypesIterator<'i> { class_stack: Vec<(usize, usize)>, // class_index, interface_index class_store: &'i ClassStore, } impl <'i>CompatibleTypesIterator<'i> { pub fn new(class_index: usize, class_store: &'i ClassStore) -> Self { CompatibleTypesIterator { class_stack: vec![(class_index, 0)], class_store, } } } impl <'i> Iterator for CompatibleTypesIterator<'i>{ type Item = &'i String; fn next(&mut self) -> Option { let (class_index, interface_index) = match self.class_stack.pop() { None => return None, Some(a) => a, }; let class_file = self.class_store.class_file_from_idx(class_index).unwrap(); if class_file.interfaces.len() == interface_index { if class_file.has_super_class() { let super_class_index = self.class_store.class_idx_from_name(class_file.get_super_class_name().unwrap()).unwrap(); self.class_stack.push((super_class_index, 0)); Some(class_file.get_super_class_name().unwrap()) } else { let recursive_next = self.next(); recursive_next } } else { let interface_name = class_file.gather_class(class_file.interfaces[interface_index]).unwrap(); let interface_class_index = self.class_store.class_idx_from_name(interface_name).unwrap(); self.class_stack.push((class_index, interface_index + 1)); self.class_stack.push((interface_class_index, 0)); Some(interface_name) } } } pub struct ClassMethodIterator<'i> { method_index: usize, class_index: usize, class_store: &'i ClassStore, } impl <'i>ClassMethodIterator<'i> { pub fn new(class_index: usize, class_store: &'i ClassStore) -> Self { ClassMethodIterator { method_index: 0, class_index, class_store, } } } impl <'i> Iterator for ClassMethodIterator<'i> { type Item = (usize, usize, &'i MethodInfo); // class index, method index, method info fn next(&mut self) -> Option { let mut class_file = self.class_store.class_file_from_idx(self.class_index).unwrap(); while class_file.has_super_class() && class_file.methods.len() == self.method_index { let super_class_name = class_file.get_super_class_name().unwrap(); let (super_class_file, super_class_index) = self.class_store.get_class(super_class_name).unwrap(); class_file = super_class_file; self.class_index = super_class_index; self.method_index = 0; } if class_file.methods.len() == self.method_index { return None; } else { let method_info = &class_file.methods[self.method_index]; self.method_index += 1; return Some((self.class_index, self.method_index - 1, method_info)); } } }