jvm/src/iterators.rs

131 lines
4.3 KiB
Rust

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<Self::Item> {
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<Self::Item> {
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<Self::Item> {
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));
}
}
}