1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::ops::Deref;
use crate::analysis::AnyEntKind;
use crate::ast::Mode;
use crate::ast::ObjectClass;
use super::AnyEnt;
use super::EntRef;
use super::Subtype;
use super::TypeEnt;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ObjectEnt<'a> {
pub ent: EntRef<'a>,
}
impl<'a> ObjectEnt<'a> {
pub fn from_any(ent: &'a AnyEnt) -> Option<Self> {
if matches!(ent.actual_kind(), AnyEntKind::Object(..)) {
Some(Self { ent })
} else {
None
}
}
pub fn kind(&self) -> &'a Object<'a> {
if let AnyEntKind::Object(object) = self.ent.actual_kind() {
object
} else {
unreachable!("ObjectEnt type invariant broken")
}
}
pub fn type_mark(&self) -> TypeEnt<'a> {
self.kind().subtype.type_mark()
}
pub fn class(&self) -> ObjectClass {
self.object().class
}
pub fn mode(&self) -> Option<Mode> {
self.object().mode
}
pub fn describe_class(&self) -> String {
if let Some(mode) = self.mode() {
if self.class() == ObjectClass::Constant {
format!("interface {}", self.describe_name())
} else {
format!("interface {} of mode {}", self.describe_name(), mode)
}
} else {
self.describe_name()
}
}
pub fn describe_name(&self) -> String {
format!("{} '{}'", self.class(), self.designator())
}
pub fn object(&self) -> &'a Object<'a> {
if let AnyEntKind::Object(object) = self.ent.actual_kind() {
object
} else {
unreachable!("Must be object");
}
}
}
#[derive(Clone)]
pub struct Object<'a> {
pub class: ObjectClass,
pub mode: Option<Mode>,
pub subtype: Subtype<'a>,
pub has_default: bool,
}
impl ObjectClass {
pub fn describe(&self) -> &str {
use ObjectClass::*;
match self {
Constant => "constant",
Variable => "variable",
Signal => "signal",
SharedVariable => "shared variable",
}
}
}
impl<'a> Deref for ObjectEnt<'a> {
type Target = EntRef<'a>;
fn deref(&self) -> &Self::Target {
&self.ent
}
}