Skip to content

Commit aedd9f5

Browse files
committed
add QL specification section on module instantiations
1 parent b572974 commit aedd9f5

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

docs/codeql/ql-language-reference/ql-language-specification.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,21 @@ Kinds of modules
199199

200200
A module may be:
201201

202+
- A *declared module*, if it is defined by the ``module`` or ``ql`` grammar rules.
203+
- A *non-declared module*, if it is not a *declared module*.
204+
205+
A *declared module* may be:
206+
202207
- A *file module*, if it is defined implicitly by a QL file or a QLL file.
203208
- A *query module*, if it is defined implicitly by a QL file.
204209
- A *library module*, if it is not a query module.
205210

211+
A *non-declared module* may be:
212+
213+
- A *built-in module*.
214+
- An *instantiated module* (see :ref:`Parameterized modules`).
215+
- An *instantiation-nested module* (see :ref:`Parameterized modules`).
216+
206217
A query module must contain one or more queries.
207218

208219
Import directives
@@ -249,6 +260,67 @@ For qualified identifiers (``a.b``):
249260

250261
A qualified module identifier is only valid within an import.
251262

263+
.. _Parameterized modules:
264+
265+
Parameterized modules
266+
~~~~~~~~~~~~~~~~~~~~~
267+
268+
Modules with parameters are called *parameterized modules*. A *declared module* has parameters if and only if it is a *library module* and its declaration uses the ``parameters`` syntax.
269+
270+
*Parameterized modules* can be instantiated with arguments that match the signatures of the parameters:
271+
272+
- Given a type signature, the corresponding argument must be a type that transitively extends the specified ``extends`` types and is a transitive subtype of the specified ``instanceof`` types.
273+
- Given a predicate signature, the corresponding argument must be a predicate with exactly matching relational types.
274+
- Given a module signature, the corresponding argument must be a module that exports all the specified type and predicate members. Furthermore, the module must be declared as matching the module signature via the ``implements`` syntax.
275+
276+
The result of instantiating a *parameterized module* is an *instantiated module*. The parameterized module is called the *underlying module* of the *instantiated module*.
277+
278+
Instantiation-relative and instantiation-nested entities
279+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280+
281+
Given an *instantiated module*, every entity has a corresponding entity called the *instantiation-relative* entity, which is determined as follows:
282+
283+
- If the entity is the *underlying module*, its *instantiation-relative entity* is the *instantiated module*.
284+
- If the entity is a parameter of the *underlying module*, its *instantiation-relative entity* is the corresponding argument.
285+
- If the entity is declared inside the *underlying module* or its nested modules, its *instantiation-relative* entity is an *instantiation-nested* entity that is generated by the module instantiation. Parameters of any modules that are nested inside the *underlying module* are considered declared inside the module for this purpose.
286+
- Otherwise, the entity's *instantiation-relative* entity is the initial entity itself.
287+
288+
When the *instantiation-relative* entity of an entity is an *instantiation-nested* entity, then the initial entity is called the *underlying nested* entity of the *instantiation-nested* entity*, the *instantiated module* is called the *instantiation root* of the *instantiation-nested* entity, and the *underlying module* is called the *underlying root* of the *instantiation-nested* entity.
289+
290+
The components of an *instantiation-nested* entity are the *instantiation-relative* entities of the components of its *underlying nested* entity. Among other things, this applies to:
291+
292+
- values in the exported environments of *instantiation-nested* modules,
293+
- relational types of *instantiation-nested* predicates and predicate signatures,
294+
- required signatures of *instantiation-nested* parameters,
295+
- parameters of an *instantiation-nested* *parameterized module*,
296+
- fields and member predicates of *instantiation-nested* dataclasses.
297+
298+
Given an *instantiated module*, any alias in the program has a corresponding alias called the *instantiation-relative* alias, which targets the *instantiation-relative* entity.
299+
300+
Applicative instantiation
301+
~~~~~~~~~~~~~~~~~~~~~~~~~
302+
303+
Every entity has an *underlying completely uninstantiated* entity that is determined as follows:
304+
305+
- If the entity is an *instantiated module*, its *underlying completely uninstantiated* entity is the *underlying completely uninstantiated* entity of the *underlying module*.
306+
- If the entity is an *instantiation-nested* entity, its *underlying completely uninstantiated* entity is the *underlying completely uninstantiated* entity of the *underlying nested* entity.
307+
- Otherwise, its *underlying completely uninstantiated* entity is the entity itself.
308+
309+
An entity is called *completely uninstantiated* entity if it is its own *underlying completely uninstantiated* entity.
310+
311+
Every *completely uninstantiated* entity has a *relevant set of parameters*, which is the set of all parameters of all the modules that the entity is transitively nested inside. For entities that are not nested inside any modules, the *relevant set of parameters* is empty.
312+
313+
Note that the *relevant set of parameters* by construction contains only *completely uninstantiated* parameters.
314+
315+
For a *completely uninstantiated* parameter, the *bottom-up instantiation-resolved* parameter relative to an entity is defined as:
316+
317+
- If the entity is an *instantiated module* or an *instantiation-nested* entity, the *bottom-up instantiation-resolved* parameter is the *instantiation-relative* parameter of the *bottom-up instantiation-resolved* parameter relative to the *underlying module*.
318+
- Otherwise, the *bottom-up instantiation-resolved* parameter is the parameter itself.
319+
320+
Two *instantiated modules* or two *instantiation-nested* entities are considered *equivalent* if they have the same *underlying completely uninstantiated* entity and each parameter in its *relevant set of parameters* has the same *bottom-up instantiation-resolved* parameter relative to either *instantiated module*.
321+
322+
Module instantiation is applicative, meaning that *equivalent* *instantiated modules* and *equivalent* *instantiation-nested* entities are indistinguishable.
323+
252324
Module references and active modules
253325
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254326

0 commit comments

Comments
 (0)