Skip to main content

lvm_class/verify/
mod.rs

1use crate::ClassFile;
2use crate::flags::ClassFlags;
3
4pub enum Finding {
5    ClassFlag(ClassFlagsFinding),
6}
7
8pub enum ClassFlagsFinding {
9    InterfaceWithoutAbstract(ClassFlags),
10    InterfaceIncompatibleFlags(ClassFlags),
11}
12
13impl ClassFlagsFinding {
14    pub fn get_flags(&self) -> ClassFlags {
15        match self {
16            ClassFlagsFinding::InterfaceWithoutAbstract(flags)
17            | ClassFlagsFinding::InterfaceIncompatibleFlags(flags) => *flags,
18        }
19    }
20}
21
22impl ClassFile {
23    pub fn verify(&self) -> Vec<Finding> {
24        let mut findings = Vec::new();
25        self.verify_interface(&mut findings);
26        findings
27    }
28
29    fn verify_interface(&self, findings: &mut Vec<Finding>) {
30        let f = self.access_flags;
31        if !f.is_interface() {
32            return;
33        }
34        if !f.is_abstract() {
35            findings.push(Finding::ClassFlag(
36                ClassFlagsFinding::InterfaceWithoutAbstract(f),
37            ));
38        }
39        if f.is_final() || f.is_super() || f.is_enum() || f.is_module() {
40            // TODO: don't use magic consts
41            let incompatible = ClassFlags::new(*f.get_raw() & (0x0010 | 0x0020 | 0x4000 | 0x8000));
42            findings.push(Finding::ClassFlag(
43                ClassFlagsFinding::InterfaceIncompatibleFlags(incompatible),
44            ));
45        }
46    }
47}