131 lines
4.3 KiB
Rust
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));
|
|
}
|
|
}
|
|
}
|