mib_rs/ir/mod.rs
1//! Intermediate representation produced by [lowering](crate::lower) the AST.
2//!
3//! The IR is language-independent: SMIv1 and SMIv2 constructs are unified
4//! (e.g. `TRAP-TYPE` and `NOTIFICATION-TYPE` both become [`Notification`]).
5//! Type and OID references remain unresolved strings until the resolver phase
6//! transforms the IR into a fully resolved [`Mib`](crate::mib::Mib).
7//!
8//! Unlike the AST, the IR uses plain `String` values instead of [`Ident`](crate::ast::Ident)
9//! nodes, and optional clauses are represented as empty strings rather than `Option`s.
10
11pub mod definition;
12pub mod oid;
13pub mod syntax;
14
15pub use definition::*;
16pub use oid::{OidAssignment, OidComponent};
17pub use syntax::*;
18
19use crate::types::{Diagnostic, Language, Span};
20
21/// A normalized, language-independent MIB module.
22///
23/// Lowering transforms AST structures into this simplified representation
24/// independent of whether the source was SMIv1 or SMIv2.
25#[derive(Debug, Clone)]
26pub struct Module {
27 /// Canonical module name (e.g. `"IF-MIB"`).
28 pub name: String,
29 /// Detected SMI language version.
30 pub language: Language,
31 /// Flattened imports: one [`Import`] per imported symbol.
32 pub imports: Vec<Import>,
33 /// All definitions in source order.
34 pub definitions: Vec<Definition>,
35 /// Span covering the entire module.
36 pub span: Span,
37 /// Diagnostics collected during lowering.
38 pub diagnostics: Vec<Diagnostic>,
39 /// File path this module was loaded from. Empty for synthetic base modules.
40 pub source_path: String,
41 /// Maps line numbers to byte offsets of line starts.
42 /// Entry i holds the byte offset where line i+1 begins (0-indexed).
43 pub line_table: Vec<usize>,
44}
45
46impl Module {
47 /// Creates a new module with the given name and span. All other fields
48 /// are initialized to empty/default values.
49 pub fn new(name: String, span: Span) -> Self {
50 Module {
51 name,
52 language: Language::Unknown,
53 imports: Vec::new(),
54 definitions: Vec::new(),
55 span,
56 diagnostics: Vec::new(),
57 source_path: String::new(),
58 line_table: Vec::new(),
59 }
60 }
61
62 /// Returns an iterator over the names of all definitions.
63 pub fn definition_names(&self) -> impl Iterator<Item = &str> {
64 self.definitions.iter().map(|d| d.name())
65 }
66}
67
68/// A single imported symbol, flattened from the AST's grouped format.
69#[derive(Debug, Clone)]
70pub struct Import {
71 /// Source module name (the FROM target).
72 pub module: String,
73 /// Imported symbol name.
74 pub symbol: String,
75 /// Source span of the symbol in the `IMPORTS` section.
76 pub span: Span,
77}