docs: fix some formatting issues

This commit is contained in:
james
2019-09-26 16:04:01 +01:00
parent 94d876e8a3
commit 3a4cef646d
14 changed files with 48 additions and 34 deletions

View File

@@ -10,6 +10,8 @@ In this example we look for all the "getters" in a program. Programmers moving t
Using the member predicate ``Function.getName()``, we can list all of the getter functions in a snapshot:
.. pull-quote::
Tip
Instead of copying this query, try typing the code. As you start to write a name that matches a library class, a pop-up is displayed making it easy for you to select the class that you want.

View File

@@ -33,7 +33,7 @@ This part of the library represents the Python source code. The ``Module``, ``Cl
Scope
^^^^^
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class and function are represented by the three classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``.
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class and function are represented by the three classes `Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__, which are all subclasses of ``Scope``.
- ``Scope``
@@ -110,12 +110,12 @@ Examples
Each syntactic element in Python source is recorded in the snapshot. These can be queried via the corresponding class. Let us start with a couple of simple examples.
1. Finding all finally blocks
'''''''''''''''''''''''''''''
1. Finding all ``finally`` blocks
'''''''''''''''''''''''''''''''''
For our first example, we can find all ``finally`` blocks by using the ``Try`` class:
**Find all ``finally`` blocks**
**Find all** ``finally`` **blocks**
.. code-block:: ql
@@ -126,8 +126,8 @@ For our first example, we can find all ``finally`` blocks by using the ``Try`` c
`See this in the query console <https://lgtm.com/query/659662193/>`__. Many projects include examples of this pattern.
2. Finding 'except' blocks that do nothing
''''''''''''''''''''''''''''''''''''''''''
2. Finding ``except`` blocks that do nothing
''''''''''''''''''''''''''''''''''''''''''''
For our second example, we can use a simplified version of a query from the standard query set. We look for all ``except`` blocks that do nothing.
@@ -137,7 +137,7 @@ A block that does nothing is one that contains no statements except ``pass`` sta
not exists(Stmt s | s = ex.getAStmt() | not s instanceof Pass)
where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`` statements. Instead of using the double negative, **"no**\ *statements that are*\ **not**\ *pass statements"*, this can also be expressed positively, "all statements must be pass statements." The positive form is expressed in QL using the ``forall`` quantifier:
where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`` statements. Instead of using the double negative, *no statements that are not pass statements*, this can also be expressed positively, *all statements must be pass statements*. The positive form is expressed in QL using the ``forall`` quantifier:
.. code-block:: ql
@@ -145,7 +145,7 @@ where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`
Both forms are equivalent. Using the positive QL expression, the whole query looks like this:
**Find pass-only ``except`` blocks**
**Find pass-only** ``except`` **blocks**
.. code-block:: ql

View File

@@ -37,7 +37,8 @@ The predicate ``ControlFlowNode.pointsTo(...)`` shows which object a control flo
predicate pointsTo(Context context, Value object, ControlFlowNode origin)
``object`` is an object that the control flow node refers to, and ``origin`` is where the object comes from, which is useful for displaying meaningful results.
The third form includes the ``context`` in which the control flow node refers to the ``object``. This form can usually be ignored.
The third form includes the ``context`` in which the control flow node refers to the ``object``. This form can usually be ignored.
.. pull-quote::
@@ -62,7 +63,7 @@ We want to find ``except`` blocks in a ``try`` statement that are in the wrong o
First we can write a query to find ordered pairs of ``except`` blocks for a ``try`` statement.
**Ordered except blocks in same ``try`` statement**
**Ordered except blocks in same** ``try`` **statement**
.. code-block:: ql
@@ -81,7 +82,7 @@ Here ``ex1`` and ``ex2`` are both ``except`` handlers in the ``try`` statement `
The results of this query need to be filtered to return only results where ``ex1`` is more general than ``ex2``. We can use the fact that an ``except`` block is more general than another block if the class it handles is a superclass of the other.
**More general ``except`` block**
**More general** ``except`` **block**
.. code-block:: ql
@@ -102,7 +103,7 @@ ensures that ``cls1`` is a ``ClassValue`` that the ``except`` block would handle
Combining the parts of the query we get this:
**More general ``except`` block precedes more specific**
**More general** ``except`` **block precedes more specific**
.. code-block:: ql

View File

@@ -143,7 +143,7 @@ Python implementations commonly cache small integers and single character string
We can check for these as follows:
**Find comparisons to integer or string literals using ``is``**
**Find comparisons to integer or string literals using** ``is``
.. code-block:: ql
@@ -158,6 +158,8 @@ We can check for these as follows:
The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` checks that the first comparison operator is "is" and that the first comparator is a literal.
.. pull-quote::
Tip
We have to use ``cmp.getOp(0)`` and ``cmp.getComparator(0)``\ as there is no ``cmp.getOp()`` or ``cmp.getComparator()``. The reason for this is that a ``Compare`` expression can have multiple operators. For example, the expression ``3 < x < 7`` has two operators and two comparators. You use ``cmp.getComparator(0)`` to get the first comparator (in this example the ``3``) and ``cmp.getComparator(1)`` to get the second comparator (in this example the ``7``).
@@ -253,9 +255,7 @@ checks that the value of the attribute (the expression to the left of the dot in
Class and function definitions
------------------------------
As Python is a dynamically typed language, class, and function definitions are executable statements. This means that a class statement is both a statement and a scope containing statements. To represent this cleanly the class definition is broken into a number of parts. At runtime, when a class definition is executed a class object is created and then assigned to a variable of the same name in the scope enclosing the class. This class is created from a code-object representing the source code for the body of the class. To represent this the ``ClassDef`` class (which represents a ``class`` statement) subclasses ``Assign``. The ``Class`` class, which represents the body of the class, can be accessed via the ``ClassDef.getDefinedClass()``
``FunctionDef``, ``Function`` are handled similarly.
As Python is a dynamically typed language, class, and function definitions are executable statements. This means that a class statement is both a statement and a scope containing statements. To represent this cleanly the class definition is broken into a number of parts. At runtime, when a class definition is executed a class object is created and then assigned to a variable of the same name in the scope enclosing the class. This class is created from a code-object representing the source code for the body of the class. To represent this the ``ClassDef`` class (which represents a ``class`` statement) subclasses ``Assign``. The ``Class`` class, which represents the body of the class, can be accessed via the ``ClassDef.getDefinedClass()``. ``FunctionDef`` and ``Function`` are handled similarly.
Here is the relevant part of the class hierarchy: