mago_codex/context/
mod.rs1use mago_atom::Atom;
2
3use crate::identifier::function_like::FunctionLikeIdentifier;
4use crate::metadata::class_like::ClassLikeMetadata;
5use crate::metadata::function_like::FunctionLikeMetadata;
6use crate::reference::ReferenceSource;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct ScopeContext<'ctx> {
10 pub(crate) function_like: Option<&'ctx FunctionLikeMetadata>,
11 pub(crate) class_like: Option<&'ctx ClassLikeMetadata>,
12 pub(crate) is_static: bool,
13}
14
15impl Default for ScopeContext<'_> {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl<'ctx> ScopeContext<'ctx> {
22 #[inline]
24 pub fn new() -> Self {
25 Self { function_like: None, class_like: None, is_static: true }
26 }
27
28 #[inline]
30 pub const fn is_global(&self) -> bool {
31 self.function_like.is_none() && self.class_like.is_none()
32 }
33
34 #[inline]
36 pub const fn is_pure(&self) -> bool {
37 if let Some(function_like) = self.function_like
38 && function_like.flags.is_pure()
39 {
40 return true;
41 }
42
43 false
44 }
45
46 #[inline]
48 pub fn get_class_like(&self) -> Option<&'ctx ClassLikeMetadata> {
49 self.class_like
50 }
51
52 #[inline]
54 pub fn get_class_like_name(&self) -> Option<Atom> {
55 self.class_like.map(|class| class.original_name)
56 }
57
58 #[inline]
60 pub fn get_function_like(&self) -> Option<&'ctx FunctionLikeMetadata> {
61 self.function_like
62 }
63
64 #[inline]
66 pub fn get_function_like_identifier(&self) -> Option<FunctionLikeIdentifier> {
67 let function_like = self.function_like?;
68
69 let Some(function_name) = function_like.name else {
70 return Some(FunctionLikeIdentifier::Closure(function_like.span.file_id, function_like.span.start));
71 };
72
73 Some(if function_like.get_kind().is_method() {
74 let Some(class_like) = self.class_like else {
75 return Some(FunctionLikeIdentifier::Function(function_name));
76 };
77
78 FunctionLikeIdentifier::Method(class_like.name, function_name)
79 } else {
80 FunctionLikeIdentifier::Function(function_name)
81 })
82 }
83
84 #[inline]
86 pub const fn is_class_like_final(&self) -> bool {
87 match self.class_like {
88 Some(class) => class.flags.is_final(),
89 None => false,
90 }
91 }
92
93 #[inline]
95 pub const fn is_static(&self) -> bool {
96 self.is_static
97 }
98
99 #[inline]
101 pub fn set_function_like(&mut self, function_like: Option<&'ctx FunctionLikeMetadata>) {
102 self.function_like = function_like;
103 }
104
105 #[inline]
107 pub fn set_class_like(&mut self, class_like: Option<&'ctx ClassLikeMetadata>) {
108 self.class_like = class_like;
109 }
110
111 #[inline]
113 pub fn set_static(&mut self, is_static: bool) {
114 self.is_static = is_static;
115 }
116
117 #[inline]
120 pub fn get_reference_source(&self) -> Option<ReferenceSource> {
121 if let Some(calling_functionlike_id) = self.get_function_like_identifier() {
122 match calling_functionlike_id {
123 FunctionLikeIdentifier::Function(name) => Some(ReferenceSource::Symbol(false, name)),
124 FunctionLikeIdentifier::Method(class_name, method_name) => {
125 Some(ReferenceSource::ClassLikeMember(false, class_name, method_name))
126 }
127 _ => None,
128 }
129 } else {
130 None
131 }
132 }
133}