Skip to main content

ferro_babe/model/
class.rs

1use rust_asm::nodes::ClassNode;
2
3use super::{ConstantPoolIndex, ConstantRef, Field, Method};
4use crate::Diagnostic;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct ClassVersion {
8    minor: u16,
9    major: u16,
10}
11
12impl ClassVersion {
13    pub(crate) const fn new(minor: u16, major: u16) -> Self {
14        Self { minor, major }
15    }
16
17    #[must_use]
18    pub fn minor(self) -> u16 {
19        self.minor
20    }
21
22    #[must_use]
23    pub fn major(self) -> u16 {
24        self.major
25    }
26}
27
28#[derive(Debug, Clone)]
29pub struct Class {
30    node: ClassNode,
31}
32
33impl Class {
34    pub(crate) fn from_node(node: ClassNode) -> Self {
35        Self { node }
36    }
37
38    #[must_use]
39    pub fn version(&self) -> ClassVersion {
40        ClassVersion {
41            minor: self.node.minor_version,
42            major: self.node.major_version,
43        }
44    }
45
46    #[must_use]
47    pub fn access_flags(&self) -> u16 {
48        self.node.access_flags
49    }
50
51    #[must_use]
52    pub fn name(&self) -> &str {
53        &self.node.name
54    }
55
56    #[must_use]
57    pub fn super_name(&self) -> Option<&str> {
58        self.node.super_name.as_deref()
59    }
60
61    #[must_use]
62    pub fn source_file(&self) -> Option<&str> {
63        self.node.source_file.as_deref()
64    }
65
66    pub fn interfaces(&self) -> impl ExactSizeIterator<Item = &str> {
67        self.node.interfaces.iter().map(String::as_str)
68    }
69
70    pub fn fields(&self) -> impl ExactSizeIterator<Item = Field<'_>> {
71        self.node.fields.iter().map(Field::new)
72    }
73
74    pub fn methods(&self) -> impl ExactSizeIterator<Item = Method<'_>> {
75        self.node
76            .methods
77            .iter()
78            .map(|method| Method::new(method, &self.node.constant_pool))
79    }
80
81    pub fn constants(&self) -> impl ExactSizeIterator<Item = (ConstantPoolIndex, ConstantRef<'_>)> {
82        self.node
83            .constant_pool
84            .iter()
85            .enumerate()
86            .map(|(index, entry)| {
87                (
88                    ConstantPoolIndex::new(index as u16),
89                    ConstantRef::from(entry),
90                )
91            })
92    }
93
94    #[must_use]
95    pub fn constant(&self, index: ConstantPoolIndex) -> Option<ConstantRef<'_>> {
96        self.node
97            .constant_pool
98            .get(index.get() as usize)
99            .map(ConstantRef::from)
100    }
101}
102
103#[derive(Debug, Clone)]
104pub struct Disassembly {
105    header: ClassVersion,
106    class: Option<Class>,
107    diagnostics: Vec<Diagnostic>,
108}
109
110impl Disassembly {
111    pub(crate) fn complete(class: Class) -> Self {
112        Self {
113            header: class.version(),
114            class: Some(class),
115            diagnostics: Vec::new(),
116        }
117    }
118
119    pub(crate) fn partial(header: ClassVersion, diagnostics: Vec<Diagnostic>) -> Self {
120        Self {
121            header,
122            class: None,
123            diagnostics,
124        }
125    }
126
127    #[must_use]
128    pub fn version(&self) -> ClassVersion {
129        self.header
130    }
131
132    #[must_use]
133    pub fn is_complete(&self) -> bool {
134        self.class.is_some()
135    }
136
137    #[must_use]
138    pub fn class(&self) -> Option<&Class> {
139        self.class.as_ref()
140    }
141
142    #[must_use]
143    pub fn diagnostics(&self) -> &[Diagnostic] {
144        &self.diagnostics
145    }
146}