mago_codex/context/
mod.rs1use mago_word::Word;
2
3use crate::identifier::function_like::FunctionLikeIdentifier;
4use crate::metadata::class_like::ClassLikeMetadata;
5use crate::metadata::function_like::FunctionLikeMetadata;
6use crate::metadata::property_hook::PropertyHookMetadata;
7use crate::reference::ReferenceOrigin;
8use crate::reference::ReferenceSource;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11#[allow(clippy::field_scoped_visibility_modifiers)]
12pub struct ScopeContext<'ctx> {
13 reference_origin: ReferenceOrigin,
14 pub(crate) function_like: Option<&'ctx FunctionLikeMetadata>,
15 pub(crate) class_like: Option<&'ctx ClassLikeMetadata>,
16 pub(crate) property_hook: Option<(Word, &'ctx PropertyHookMetadata)>,
17 pub(crate) is_static: bool,
18}
19
20impl<'ctx> ScopeContext<'ctx> {
21 #[inline]
23 #[must_use]
24 pub const fn new(reference_origin: ReferenceOrigin) -> Self {
25 Self { reference_origin, function_like: None, class_like: None, property_hook: None, is_static: true }
26 }
27
28 #[inline]
30 #[must_use]
31 pub const fn get_reference_origin(&self) -> ReferenceOrigin {
32 self.reference_origin
33 }
34
35 #[inline]
37 #[must_use]
38 pub const fn is_global(&self) -> bool {
39 self.function_like.is_none() && self.class_like.is_none()
40 }
41
42 #[inline]
44 #[must_use]
45 pub const fn is_pure(&self) -> bool {
46 if let Some(function_like) = self.function_like
47 && function_like.flags.is_pure()
48 {
49 return true;
50 }
51
52 false
53 }
54
55 #[inline]
57 #[must_use]
58 pub fn get_class_like(&self) -> Option<&'ctx ClassLikeMetadata> {
59 self.class_like
60 }
61
62 #[inline]
64 #[must_use]
65 pub fn get_class_like_name(&self) -> Option<Word> {
66 self.class_like.map(|class| class.name)
67 }
68
69 #[inline]
71 #[must_use]
72 pub fn get_function_like(&self) -> Option<&'ctx FunctionLikeMetadata> {
73 self.function_like
74 }
75
76 #[inline]
78 #[must_use]
79 pub fn get_function_like_identifier(&self) -> Option<FunctionLikeIdentifier> {
80 let function_like = self.function_like?;
81 let function_name = function_like.name;
82
83 if function_like.get_kind().is_method() {
84 if let Some(class_like) = self.class_like {
85 return Some(FunctionLikeIdentifier::Method(class_like.name, function_name));
86 }
87
88 return Some(FunctionLikeIdentifier::Function(function_name));
89 }
90
91 let kind = function_like.get_kind();
92 if kind.is_closure() || kind.is_arrow_function() {
93 return Some(FunctionLikeIdentifier::Closure(function_name));
94 }
95
96 Some(FunctionLikeIdentifier::Function(function_name))
97 }
98
99 #[inline]
101 #[must_use]
102 pub const fn is_class_like_final(&self) -> bool {
103 match self.class_like {
104 Some(class) => class.flags.is_final(),
105 None => false,
106 }
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn is_static(&self) -> bool {
113 self.is_static
114 }
115
116 #[inline]
118 pub fn set_function_like(&mut self, function_like: Option<&'ctx FunctionLikeMetadata>) {
119 self.function_like = function_like;
120 }
121
122 #[inline]
124 pub fn set_class_like(&mut self, class_like: Option<&'ctx ClassLikeMetadata>) {
125 self.class_like = class_like;
126 }
127
128 #[inline]
130 pub fn set_static(&mut self, is_static: bool) {
131 self.is_static = is_static;
132 }
133
134 #[inline]
138 #[must_use]
139 pub fn get_property_hook(&self) -> Option<(Word, &'ctx PropertyHookMetadata)> {
140 self.property_hook
141 }
142
143 #[inline]
147 pub fn set_property_hook(&mut self, property_hook: Option<(Word, &'ctx PropertyHookMetadata)>) {
148 self.property_hook = property_hook;
149 }
150
151 #[inline]
154 #[must_use]
155 pub fn get_reference_source(&self) -> Option<ReferenceSource> {
156 match self.reference_origin {
157 ReferenceOrigin::Symbol((symbol, member)) if member.is_empty() => {
158 Some(ReferenceSource::Symbol(false, symbol))
159 }
160 ReferenceOrigin::Symbol((symbol, member)) => Some(ReferenceSource::ClassLikeMember(false, symbol, member)),
161 ReferenceOrigin::File(file) => Some(ReferenceSource::File(false, file)),
162 }
163 }
164}