Skip to content

context

Hold the mutable semantic-analysis state that is shared across node visits and, in multi-module mode, across modules in one session.

Classes:

SemanticContext dataclass

SemanticContext(
    scopes: ScopeStack = ScopeStack(),
    diagnostics: DiagnosticBag = DiagnosticBag(),
    functions: dict[
        tuple[ModuleKey, str], SemanticFunction
    ] = dict(),
    structs: dict[
        tuple[ModuleKey, str], SemanticStruct
    ] = dict(),
    classes: dict[
        tuple[ModuleKey, str], SemanticClass
    ] = dict(),
    current_function: SemanticFunction | None = None,
    current_class: SemanticClass | None = None,
    current_module_key: ModuleKey | None = None,
    loop_depth: int = 0,
    _symbol_counter: int = 0,
    _method_slot_counter: int = 0,
)

Store scopes, diagnostics, module-aware top-level registries, and transient current-node context for the analyzer. attributes: scopes: type: ScopeStack diagnostics: type: DiagnosticBag functions: type: dict[tuple[ModuleKey, str], SemanticFunction] structs: type: dict[tuple[ModuleKey, str], SemanticStruct] classes: type: dict[tuple[ModuleKey, str], SemanticClass] current_function: type: SemanticFunction | None current_class: type: SemanticClass | None current_module_key: type: ModuleKey | None loop_depth: type: int _symbol_counter: type: int _method_slot_counter: type: int

Methods:

get_class

get_class(
    module_key: ModuleKey, name: str
) -> SemanticClass | None

Retrieve the canonical semantic class for one module-qualified top- level name. parameters: module_key: type: ModuleKey name: type: str returns: type: SemanticClass | None

Source code in packages/irx/src/irx/analysis/context.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def get_class(
    self,
    module_key: ModuleKey,
    name: str,
) -> SemanticClass | None:
    """
    title: Return a top-level class by module and name.
    summary: >-
      Retrieve the canonical semantic class for one module-qualified top-
      level name.
    parameters:
      module_key:
        type: ModuleKey
      name:
        type: str
    returns:
      type: SemanticClass | None
    """
    return self.classes.get((module_key, name))

get_function

get_function(
    module_key: ModuleKey, name: str
) -> SemanticFunction | None

Retrieve the canonical semantic function for one module-qualified top-level name. parameters: module_key: type: ModuleKey name: type: str returns: type: SemanticFunction | None

Source code in packages/irx/src/irx/analysis/context.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def get_function(
    self,
    module_key: ModuleKey,
    name: str,
) -> SemanticFunction | None:
    """
    title: Return a top-level function by module and name.
    summary: >-
      Retrieve the canonical semantic function for one module-qualified
      top-level name.
    parameters:
      module_key:
        type: ModuleKey
      name:
        type: str
    returns:
      type: SemanticFunction | None
    """
    return self.functions.get((module_key, name))

get_struct

get_struct(
    module_key: ModuleKey, name: str
) -> SemanticStruct | None

Retrieve the canonical semantic struct for one module-qualified top- level name. parameters: module_key: type: ModuleKey name: type: str returns: type: SemanticStruct | None

Source code in packages/irx/src/irx/analysis/context.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def get_struct(
    self,
    module_key: ModuleKey,
    name: str,
) -> SemanticStruct | None:
    """
    title: Return a top-level struct by module and name.
    summary: >-
      Retrieve the canonical semantic struct for one module-qualified top-
      level name.
    parameters:
      module_key:
        type: ModuleKey
      name:
        type: str
    returns:
      type: SemanticStruct | None
    """
    return self.structs.get((module_key, name))

in_class

in_class(class_: SemanticClass) -> Iterator[None]

Remember which class declaration is being analyzed so inheritance and member-semantics helpers can consult the active owner. parameters: class_: type: SemanticClass returns: type: Iterator[None]

Source code in packages/irx/src/irx/analysis/context.py
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
@contextmanager
def in_class(self, class_: SemanticClass) -> Iterator[None]:
    """
    title: Temporarily set current_class.
    summary: >-
      Remember which class declaration is being analyzed so inheritance and
      member-semantics helpers can consult the active owner.
    parameters:
      class_:
        type: SemanticClass
    returns:
      type: Iterator[None]
    """
    previous = self.current_class
    self.current_class = class_
    try:
        yield
    finally:
        self.current_class = previous

in_function

in_function(function: SemanticFunction) -> Iterator[None]

Remember which function body is being analyzed so return and control- flow rules can consult it. parameters: function: type: SemanticFunction returns: type: Iterator[None]

Source code in packages/irx/src/irx/analysis/context.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
@contextmanager
def in_function(self, function: SemanticFunction) -> Iterator[None]:
    """
    title: Temporarily set current_function.
    summary: >-
      Remember which function body is being analyzed so return and control-
      flow rules can consult it.
    parameters:
      function:
        type: SemanticFunction
    returns:
      type: Iterator[None]
    """
    previous = self.current_function
    self.current_function = function
    try:
        yield
    finally:
        self.current_function = previous

in_loop

in_loop() -> Iterator[None]

Mark a temporary loop region so break and continue validation can see that loop nesting exists. returns: type: Iterator[None]

Source code in packages/irx/src/irx/analysis/context.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
@contextmanager
def in_loop(self) -> Iterator[None]:
    """
    title: Increase loop depth for loop analysis.
    summary: >-
      Mark a temporary loop region so break and continue validation can see
      that loop nesting exists.
    returns:
      type: Iterator[None]
    """
    self.loop_depth += 1
    try:
        yield
    finally:
        self.loop_depth -= 1

in_module

in_module(module_key: ModuleKey) -> Iterator[None]

Switch the active module identity so registrations and diagnostics are attributed to the right module. parameters: module_key: type: ModuleKey returns: type: Iterator[None]

Source code in packages/irx/src/irx/analysis/context.py
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
@contextmanager
def in_module(self, module_key: ModuleKey) -> Iterator[None]:
    """
    title: Temporarily set the current module key.
    summary: >-
      Switch the active module identity so registrations and diagnostics
      are attributed to the right module.
    parameters:
      module_key:
        type: ModuleKey
    returns:
      type: Iterator[None]
    """
    previous = self.current_module_key
    previous_diagnostic_key = self.diagnostics.default_module_key
    self.current_module_key = module_key
    self.diagnostics.default_module_key = module_key
    try:
        yield
    finally:
        self.current_module_key = previous
        self.diagnostics.default_module_key = previous_diagnostic_key

next_method_slot

next_method_slot() -> int

Generate a deterministic dispatch-table slot index for one newly introduced overridable instance method. returns: type: int

Source code in packages/irx/src/irx/analysis/context.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def next_method_slot(self) -> int:
    """
    title: Return a fresh class-method dispatch slot.
    summary: >-
      Generate a deterministic dispatch-table slot index for one newly
      introduced overridable instance method.
    returns:
      type: int
    """
    slot = self._method_slot_counter
    self._method_slot_counter += 1
    return slot

next_symbol_id

next_symbol_id(prefix: str) -> str

Generate a unique semantic id for locals and declarations that need stable identity inside one analysis run. parameters: prefix: type: str returns: type: str

Source code in packages/irx/src/irx/analysis/context.py
79
80
81
82
83
84
85
86
87
88
89
90
91
92
def next_symbol_id(self, prefix: str) -> str:
    """
    title: Return a fresh semantic symbol id.
    summary: >-
      Generate a unique semantic id for locals and declarations that need
      stable identity inside one analysis run.
    parameters:
      prefix:
        type: str
    returns:
      type: str
    """
    self._symbol_counter += 1
    return f"{prefix}:{self._symbol_counter}"

register_class

register_class(class_: SemanticClass) -> None

Store the canonical semantic class object for one module-qualified top-level name. parameters: class_: type: SemanticClass

Source code in packages/irx/src/irx/analysis/context.py
171
172
173
174
175
176
177
178
179
180
181
def register_class(self, class_: SemanticClass) -> None:
    """
    title: Register a top-level class by module and name.
    summary: >-
      Store the canonical semantic class object for one module-qualified
      top-level name.
    parameters:
      class_:
        type: SemanticClass
    """
    self.classes[(class_.module_key, class_.name)] = class_

register_function

register_function(function: SemanticFunction) -> None

Store the canonical semantic function object for one module-qualified top-level name. parameters: function: type: SemanticFunction

Source code in packages/irx/src/irx/analysis/context.py
107
108
109
110
111
112
113
114
115
116
117
def register_function(self, function: SemanticFunction) -> None:
    """
    title: Register a top-level function by module and name.
    summary: >-
      Store the canonical semantic function object for one module-qualified
      top-level name.
    parameters:
      function:
        type: SemanticFunction
    """
    self.functions[(function.module_key, function.name)] = function

register_struct

register_struct(struct: SemanticStruct) -> None

Store the canonical semantic struct object for one module-qualified top-level name. parameters: struct: type: SemanticStruct

Source code in packages/irx/src/irx/analysis/context.py
139
140
141
142
143
144
145
146
147
148
149
def register_struct(self, struct: SemanticStruct) -> None:
    """
    title: Register a top-level struct by module and name.
    summary: >-
      Store the canonical semantic struct object for one module-qualified
      top-level name.
    parameters:
      struct:
        type: SemanticStruct
    """
    self.structs[(struct.module_key, struct.name)] = struct

scope

scope(kind: str) -> Iterator[None]

Temporarily add a lexical scope frame while analyzing a block of statements. parameters: kind: type: str returns: type: Iterator[None]

Source code in packages/irx/src/irx/analysis/context.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
@contextmanager
def scope(self, kind: str) -> Iterator[None]:
    """
    title: Push/pop a scope around a block of work.
    summary: >-
      Temporarily add a lexical scope frame while analyzing a block of
      statements.
    parameters:
      kind:
        type: str
    returns:
      type: Iterator[None]
    """
    self.scopes.push(kind)
    try:
        yield
    finally:
        self.scopes.pop()