Fix trailing whitespace in docs

This commit is contained in:
Nora Dimitrijević
2024-09-24 11:53:26 +02:00
parent 5a4cd1c578
commit 26ac84aa6e
3 changed files with 103 additions and 103 deletions

View File

@@ -27,8 +27,8 @@ This example of an extensible predicate for a source is taken from the core Java
.. code-block:: ql
extensible predicate sourceModel(
string package, string type, boolean subtypes, string name,
string signature, string ext, string output, string kind,
string package, string type, boolean subtypes, string name,
string signature, string ext, string output, string kind,
string provenance
);

View File

@@ -4,10 +4,10 @@
Modules
#######
Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules.
You can import modules into other files, which avoids duplication, and helps
Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules.
You can import modules into other files, which avoids duplication, and helps
structure your code into more manageable pieces.
.. _defining-module:
@@ -16,7 +16,7 @@ Defining a module
*****************
There are various ways to define modules—here is an example of the simplest way, declaring an
:ref:`explicit module <explicit-modules>` named ``Example`` containing
:ref:`explicit module <explicit-modules>` named ``Example`` containing
a class ``OneTwoThree``:
.. code-block:: ql
@@ -27,17 +27,17 @@ a class ``OneTwoThree``:
this = 1 or this = 2 or this = 3
}
}
}
}
The name of a module can be any `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
that starts with an uppercase or lowercase letter.
that starts with an uppercase or lowercase letter.
``.ql`` or ``.qll`` files also implicitly define modules.
For more information, see ":ref:`kinds-of-modules`."
You can also annotate a module. For more information, see of ":ref:`annotations-overview`."
Note that you can only annotate :ref:`explicit modules <explicit-modules>`.
Note that you can only annotate :ref:`explicit modules <explicit-modules>`.
File modules cannot be annotated.
.. _kinds-of-modules:
@@ -48,7 +48,7 @@ Kinds of modules
File modules
============
Each query file (extension ``.ql``) and library file (extension ``.qll``) implicitly defines
Each query file (extension ``.ql``) and library file (extension ``.qll``) implicitly defines
a module. The module has the same name as the file, but any spaces in the file name are replaced
by underscores (``_``). The contents of the file form the :ref:`body of the module <module-bodies>`.
@@ -57,7 +57,7 @@ by underscores (``_``). The contents of the file form the :ref:`body of the modu
Library modules
---------------
A library module is defined by a ``.qll`` file. It can contain any of the
A library module is defined by a ``.qll`` file. It can contain any of the
elements listed in :ref:`module-bodies` below, apart from select clauses.
For example, consider the following QL library:
@@ -75,19 +75,19 @@ For example, consider the following QL library:
This file defines a library module named ``OneTwoThreeLib``. The body of this module
defines the class ``OneTwoThree``.
.. _query-modules:
.. _query-modules:
Query modules
-------------
A query module is defined by a ``.ql`` file. It can contain any of the elements listed
in :ref:`module-bodies` below.
A query module is defined by a ``.ql`` file. It can contain any of the elements listed
in :ref:`module-bodies` below.
Query modules are slightly different from other modules:
- A query module can't be imported.
- A query module must have at least one query in its
:ref:`namespace <namespaces>`. This is usually a :ref:`select clause <select-clauses>`,
- A query module must have at least one query in its
:ref:`namespace <namespaces>`. This is usually a :ref:`select clause <select-clauses>`,
but can also be a :ref:`query predicate <query-predicates>`.
For example:
@@ -97,7 +97,7 @@ For example:
.. code-block:: ql
import OneTwoThreeLib
from OneTwoThree ott
where ott = 1 or ott = 2
select ott
@@ -110,13 +110,13 @@ This file defines a query module named ``OneTwoQuery``. The body of this module
Explicit modules
================
You can also define a module within another module. This is an explicit module definition.
You can also define a module within another module. This is an explicit module definition.
An explicit module is defined with the keyword ``module`` followed by
the module name, and then the module body enclosed in braces. It can contain any
of the elements listed in ":ref:`module-bodies`" below, apart from select clauses.
An explicit module is defined with the keyword ``module`` followed by
the module name, and then the module body enclosed in braces. It can contain any
of the elements listed in ":ref:`module-bodies`" below, apart from select clauses.
For example, you could add the following QL snippet to the library file **OneTwoThreeLib.qll**
For example, you could add the following QL snippet to the library file **OneTwoThreeLib.qll**
defined :ref:`above <library-modules>`:
.. code-block:: ql
@@ -129,7 +129,7 @@ defined :ref:`above <library-modules>`:
}
}
}
This defines an explicit module named ``M``. The body of this module defines
the class ``OneTwo``.
@@ -226,7 +226,7 @@ Module bodies
*************
The body of a module is the code inside the module definition, for example
the class ``OneTwo`` in the :ref:`explicit module <explicit-modules>` ``M``.
the class ``OneTwo`` in the :ref:`explicit module <explicit-modules>` ``M``.
In general, the body of a module can contain the following constructs:
@@ -243,11 +243,11 @@ In general, the body of a module can contain the following constructs:
Importing modules
*****************
The main benefit of storing code in a module is that you can reuse it in other modules.
To access the contents of an external module, you can import the module using an
The main benefit of storing code in a module is that you can reuse it in other modules.
To access the contents of an external module, you can import the module using an
:ref:`import statement <import-statements>`.
When you import a module this brings all the names in its namespace, apart from :ref:`private` names,
When you import a module this brings all the names in its namespace, apart from :ref:`private` names,
into the :ref:`namespace <namespaces>` of the current module.
.. _import-statements:
@@ -263,7 +263,7 @@ Import statements are used for importing modules. They are of the form:
import <module_expression2>
Import statements are usually listed at the beginning of the module. Each
import statement imports one module. You can import multiple modules by
import statement imports one module. You can import multiple modules by
including multiple import statements (one for each module you want to import).
An import statement can also be :ref:`annotated <annotations-overview>` with
@@ -272,14 +272,14 @@ An import statement can also be :ref:`annotated <annotations-overview>` with
only reachable through deprecated imports in a given context then usage of the
name in that context will generate deprecation warnings.
You can import a module under a different name using the ``as`` keyword,
You can import a module under a different name using the ``as`` keyword,
for example ``import javascript as js``.
The ``<module_expression>`` itself can be a module name, a selection, or a qualified
reference. For more information, see ":ref:`name-resolution`."
For information about how import statements are looked up, see "`Module resolution <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#module-resolution>`__"
in the QL language specification.
in the QL language specification.
Built-in modules
****************
@@ -353,7 +353,7 @@ Sets
The built-in ``InternSets`` module is parameterized by ``Key`` and ``Value`` types
and a ``Value getAValue(Key key)`` relation. The module groups the ``Value``
column by ``Key`` and creates a set for each group of values related by a key.
column by ``Key`` and creates a set for each group of values related by a key.
The ``InternSets`` module exports a functional ``Set getSet(Key key)`` relation
that relates keys with the set of value related to the given key by

View File

@@ -10,12 +10,12 @@ Types
QL is a statically typed language, so each variable must have a declared type.
A type is a set of values.
For example, the type ``int`` is the set of integers.
Note that a value can belong to more than one of these sets, which means that it can have more
For example, the type ``int`` is the set of integers.
Note that a value can belong to more than one of these sets, which means that it can have more
than one type.
The kinds of types in QL are :ref:`primitive types <primitive-types>`, :ref:`classes <classes>`,
:ref:`character types <character-types>`, :ref:`class domain types <domain-types>`,
:ref:`character types <character-types>`, :ref:`class domain types <domain-types>`,
:ref:`algebraic datatypes <algebraic-datatypes>`, :ref:`type unions <type-unions>`,
and :ref:`database types <database-types>`.
@@ -31,23 +31,23 @@ independent of the database that you are querying.
.. _boolean:
#. **boolean**: This type contains the values ``true`` and ``false``.
.. _float:
#. **float**: This type contains 64-bit floating point numbers, such as ``6.28`` and ``-0.618``.
.. _int:
#. **int**: This type contains 32-bit `two's complement <https://en.wikipedia.org/wiki/Two%27s_complement>`_ integers, such as ``-1`` and ``42``.
.. _string:
#. **string**: This type contains finite strings of 16-bit characters.
.. _date:
#. **date**: This type contains dates (and optionally times).
#. **date**: This type contains dates (and optionally times).
QL has a range of built-in operations defined on primitive types. These are available by using dispatch on expressions of the appropriate type. For example, ``1.toString()`` is the string representation of the integer constant ``1``. For a full list of built-in operations available in QL, see the
section on `built-ins <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#built-ins>`__ in the QL language specification.
@@ -65,7 +65,7 @@ Classes provide an easy way to reuse and structure code. For example, you can:
- Define :ref:`member predicates <member-predicates>` on those values.
- Define subclasses that :ref:`override member predicates <overriding-member-predicates>`.
A class in QL doesn't "create" a new object, it just represents a logical property. A value is
A class in QL doesn't "create" a new object, it just represents a logical property. A value is
in a particular class if it satisfies that logical property.
.. _defining-a-class:
@@ -75,8 +75,8 @@ Defining a class
To define a class, you write:
#. The keyword ``class``.
#. The name of the class. This is an `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
#. The keyword ``class``.
#. The name of the class. This is an `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
starting with an uppercase letter.
#. The supertypes that the class is derived from via `extends` and/or `instanceof`
#. The :ref:`body of the class <class-bodies>`, enclosed in braces.
@@ -89,11 +89,11 @@ For example:
OneTwoThree() { // characteristic predicate
this = 1 or this = 2 or this = 3
}
string getAString() { // member predicate
result = "One, two or three: " + this.toString()
}
predicate isEven() { // member predicate
this = 2
}
@@ -101,7 +101,7 @@ For example:
This defines a class ``OneTwoThree``, which contains the values ``1``, ``2``, and ``3``. The
:ref:`characteristic predicate <characteristic-predicates>` captures the logical property of
"being one of the integers 1, 2, or 3."
"being one of the integers 1, 2, or 3."
.. index:: extends
@@ -132,12 +132,12 @@ Class bodies
The body of a class can contain:
- A :ref:`characteristic predicate <characteristic-predicates>` declaration.
- Any number of :ref:`member predicate <member-predicates>` declarations.
- Any number of :ref:`field <fields>` declarations.
- Any number of :ref:`field <fields>` declarations.
When you define a class, that class also inherits all non-:ref:`private` member predicates and
fields from its supertypes.
Depending on whether they are final, you can :ref:`override <overriding-member-predicates>` or
Depending on whether they are final, you can :ref:`override <overriding-member-predicates>` or
:ref:`shadow <final-extensions>` those predicates and fields to give them a more specific definition.
.. _characteristic-predicates:
@@ -181,22 +181,22 @@ This call returns ``"ONE, TWO OR THREE: 1"``.
.. pull-quote:: Note
Characteristic predicates and member predicates often use the variable ``this``.
This variable always refers to a member of the class—in this case a value belonging to the
Characteristic predicates and member predicates often use the variable ``this``.
This variable always refers to a member of the class—in this case a value belonging to the
class ``OneTwoThree``.
In the :ref:`characteristic predicate <characteristic-predicates>`, the variable ``this``
In the :ref:`characteristic predicate <characteristic-predicates>`, the variable ``this``
constrains the values that are in the class.
In a :ref:`member predicate <member-predicates>`, ``this`` acts in the same way as any
In a :ref:`member predicate <member-predicates>`, ``this`` acts in the same way as any
other argument to the predicate.
.. index:: field
.. _fields:
.. _fields:
Fields
------
These are variables declared in the body of a class. A class can have any number of field
declarations (that is, variable declarations) within its body. You can use these variables in
declarations (that is, variable declarations) within its body. You can use these variables in
predicate declarations inside the class. Much like the :ref:`variable <this>` ``this``, fields
must be constrained in the :ref:`characteristic predicate <characteristic-predicates>`.
@@ -207,21 +207,21 @@ For example:
class SmallInt extends int {
SmallInt() { this = [1 .. 10] }
}
class DivisibleInt extends SmallInt {
SmallInt divisor; // declaration of the field `divisor`
DivisibleInt() { this % divisor = 0 }
SmallInt getADivisor() { result = divisor }
}
from DivisibleInt i
select i, i.getADivisor()
In this example, the declaration ``SmallInt divisor`` introduces a field ``divisor``, constrains
it in the characteristic predicate, and then uses it in the declaration of the member predicate
``getADivisor``. This is similar to introducing variables in a :ref:`select clause <select-clauses>`
by declaring them in the ``from`` part.
by declaring them in the ``from`` part.
You can also annotate predicates and fields. See the list of :ref:`annotations <annotations-overview>`
that are available.
@@ -231,7 +231,7 @@ that are available.
Concrete classes
================
The classes in the above examples are all **concrete** classes. They are defined by
The classes in the above examples are all **concrete** classes. They are defined by
restricting the values in a larger type. The values in a concrete class are precisely those
values in the intersection of the supertypes that also satisfy the
:ref:`characteristic predicate <characteristic-predicates>` of the class.
@@ -241,32 +241,32 @@ values in the intersection of the supertypes that also satisfy the
Abstract classes
================
A class :ref:`annotated <abstract>` with ``abstract``, known as an **abstract** class, is also a restriction of
the values in a larger type. However, an abstract class is defined as the union of its
subclasses. In particular, for a value to be in an abstract class, it must satisfy the
A class :ref:`annotated <abstract>` with ``abstract``, known as an **abstract** class, is also a restriction of
the values in a larger type. However, an abstract class is defined as the union of its
subclasses. In particular, for a value to be in an abstract class, it must satisfy the
characteristic predicate of the class itself **and** the characteristic predicate of a subclass.
Note that final extensions are not considered subclasses in this context.
An abstract class is useful if you want to group multiple existing classes together
under a common name. You can then define member predicates on all those classes. You can also
extend predefined abstract classes: for example, if you import a library that contains an
An abstract class is useful if you want to group multiple existing classes together
under a common name. You can then define member predicates on all those classes. You can also
extend predefined abstract classes: for example, if you import a library that contains an
abstract class, you can add more subclasses to it.
**Example**
If you are writing a security query, you may be interested in identifying
all expressions that can be interpreted as SQL queries.
If you are writing a security query, you may be interested in identifying
all expressions that can be interpreted as SQL queries.
You can use the following abstract class to describe these expressions:
.. code-block:: ql
abstract class SqlExpr extends Expr {
...
...
}
Now define various subclasses—one for each kind of database management system. For example, you
can define a subclass ``class PostgresSqlExpr extends SqlExpr``, which contains expressions
passed to some Postgres API that performs a database query.
can define a subclass ``class PostgresSqlExpr extends SqlExpr``, which contains expressions
passed to some Postgres API that performs a database query.
You can define similar subclasses for MySQL and other database management systems.
The abstract class ``SqlExpr`` refers to all of those different expressions. If you want to add
@@ -278,7 +278,7 @@ there is no need to update the queries that rely on it.
You must take care when you add a new subclass to an existing abstract class. Adding a subclass
is not an isolated change, it also extends the abstract class since that is a union of its
subclasses.
subclasses.
.. _overriding-member-predicates:
@@ -288,7 +288,7 @@ Overriding member predicates
If a class inherits a member predicate from a non-final supertype, you can **override** the
inherited definition. You do this by defining a member predicate with the same name and arity
as the inherited predicate, and by adding the ``override`` :ref:`annotation <override>`.
This is useful if you want to refine the predicate to give a more specific result for the
This is useful if you want to refine the predicate to give a more specific result for the
values in the subclass.
For example, extending the class from the :ref:`first example <defining-a-class>`:
@@ -299,7 +299,7 @@ For example, extending the class from the :ref:`first example <defining-a-class>
OneTwo() {
this = 1 or this = 2
}
override string getAString() {
result = "One or two: " + this.toString()
}
@@ -328,7 +328,7 @@ look like this:
| 3 | One, two or three: 3 |
+---+-------------------------+
In QL, unlike other object-oriented languages, different subtypes of the same types don't need to be
In QL, unlike other object-oriented languages, different subtypes of the same types don't need to be
disjoint. For example, you could define another subclass of ``OneTwoThree``, which overlaps
with ``OneTwo``:
@@ -338,14 +338,14 @@ with ``OneTwo``:
TwoThree() {
this = 2 or this = 3
}
override string getAString() {
result = "Two or three: " + this.toString()
}
}
Now the value 2 is included in both class types ``OneTwo`` and ``TwoThree``. Both of these classes
override the original definition of ``getAString()``. There are two new "most specific" definitions,
Now the value 2 is included in both class types ``OneTwo`` and ``TwoThree``. Both of these classes
override the original definition of ``getAString()``. There are two new "most specific" definitions,
so running the above query gives the following results:
+---+-------------------------+
@@ -373,7 +373,7 @@ For example, using the definitions from the above section:
class Two extends OneTwo, TwoThree {}
Any value in the class ``Two`` must satisfy the logical property represented by ``OneTwo``,
Any value in the class ``Two`` must satisfy the logical property represented by ``OneTwo``,
**and** the logical property represented by ``TwoThree``. Here the class ``Two`` contains one
value, namely 2.
@@ -401,12 +401,12 @@ For example, extending the class from the :ref:`first example <defining-a-class>
.. code-block:: ql
final class FinalOneTwoThree = OneTwoThree;
class OneTwoFinalExtension extends FinalOneTwoThree {
OneTwoFinalExtension() {
this = 1 or this = 2
}
string getAString() {
result = "One or two: " + this.toString()
}
@@ -507,19 +507,19 @@ Had ``Bar`` been defined as ``extends Foo``, then ``select any(Foo f).foo()`` wo
Character types and class domain types
**************************************
You can't refer to these types directly, but each class in QL implicitly defines a character
type and a class domain type. (These are rather more subtle concepts and don't appear very
You can't refer to these types directly, but each class in QL implicitly defines a character
type and a class domain type. (These are rather more subtle concepts and don't appear very
often in practical query writing.)
The **character type** of a QL class is the set of values satisfying the :ref:`characteristic
predicate <characteristic-predicates>` of the class.
It is a subset of the domain type. For concrete classes, a value belongs to
the class if, and only if, it is in the character type. For :ref:`abstract classes
The **character type** of a QL class is the set of values satisfying the :ref:`characteristic
predicate <characteristic-predicates>` of the class.
It is a subset of the domain type. For concrete classes, a value belongs to
the class if, and only if, it is in the character type. For :ref:`abstract classes
<abstract-classes>`, a value must also belong to at least one of the subclasses, in addition to
being in the character type.
being in the character type.
The **domain type** of a QL class is the intersection of the character types of all its supertypes, that is, a value
belongs to the domain type if it belongs to every supertype. It occurs as the type of ``this``
belongs to the domain type if it belongs to every supertype. It occurs as the type of ``this``
in the characteristic predicate of a class.
.. index:: newtype
@@ -570,13 +570,13 @@ The branch definitions have the following form:
<BranchName>(<arguments>) { <body> }
- The type name and the branch names must be `identifiers <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
- The type name and the branch names must be `identifiers <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
starting with an uppercase letter. Conventionally, they start with ``T``.
- The different branches of an algebraic datatype are separated by ``or``.
- The arguments to a branch, if any, are :ref:`variable declarations <variable-declarations>`
separated by commas.
- The body of a branch is a :ref:`predicate <predicates>` body. You can omit the branch body, in which case
it defaults to ``any()``.
it defaults to ``any()``.
Note that branch bodies are evaluated fully, so they must be finite. They should be kept small
for good performance.
@@ -586,28 +586,28 @@ For example, the following algebraic datatype has three branches:
newtype T =
Type1(A a, B b) { body(a, b) }
or
or
Type2(C c)
or
or
Type3()
Standard pattern for using algebraic datatypes
==============================================
Algebraic datatypes are different from :ref:`classes <classes>`. In particular, algebraic datatypes don't have a
Algebraic datatypes are different from :ref:`classes <classes>`. In particular, algebraic datatypes don't have a
``toString()`` member predicate, so you can't use them in a :ref:`select clause <select-clauses>`.
Classes are often used to extend algebraic datatypes (and to provide a ``toString()`` predicate).
Classes are often used to extend algebraic datatypes (and to provide a ``toString()`` predicate).
In the standard QL language libraries, this is usually done as follows:
- Define a class ``A`` that extends the algebraic datatype and optionally declares :ref:`abstract`
predicates.
- For each branch type, define a class ``B`` that extends both ``A`` and the branch type,
- For each branch type, define a class ``B`` that extends both ``A`` and the branch type,
and provide a definition for any abstract predicates from ``A``.
- Annotate the algebraic datatype with :ref:`private`, and leave the classes public.
For example, the following code snippet from the CodeQL data-flow library for C# defines classes
for dealing with tainted or untainted values. In this case, it doesn't make sense for
for dealing with tainted or untainted values. In this case, it doesn't make sense for
``TaintType`` to extend a database type. It is part of the taint analysis, not the underlying
program, so it's helpful to extend a new type (namely ``TTaintType``):
@@ -617,24 +617,24 @@ program, so it's helpful to extend a new type (namely ``TTaintType``):
TExactValue()
or
TTaintedValue()
/** Describes how data is tainted. */
class TaintType extends TTaintType {
string toString() {
this = TExactValue() and result = "exact"
or
or
this = TTaintedValue() and result = "tainted"
}
}
/** A taint type where the data is untainted. */
class Untainted extends TaintType, TExactValue {
}
/** A taint type where the data is tainted. */
class Tainted extends TaintType, TTaintedValue {
}
.. _type-unions:
Type unions
@@ -672,7 +672,7 @@ If we had implemented ``DefiniteInitialization`` as a class extension instead, i
.. code-block:: ql
// THIS WON'T WORK: The implicit type check for InitialValueSource involves an illegal recursion
// THIS WON'T WORK: The implicit type check for InitialValueSource involves an illegal recursion
// DefiniteInitialization -> InitialValueSource -> UnknownInitialGarbage -> ¬DefiniteInitialization!
class DefiniteInitialization extends InitialValueSource {
DefiniteInitialization() {
@@ -692,7 +692,7 @@ Database types are defined in the database schema. This means that they depend o
that you are querying, and vary according to the data you are analyzing.
For example, if you are querying a CodeQL database for a Java project, the database types may
include ``@ifstmt``, representing an if statement in the Java code, and ``@variable``,
include ``@ifstmt``, representing an if statement in the Java code, and ``@variable``,
representing a variable.
.. _type-compatibility: