diff --git a/docs/language/ql-handbook/predicates.rst b/docs/language/ql-handbook/predicates.rst index 091488f64b3..d2da73be3ce 100644 --- a/docs/language/ql-handbook/predicates.rst +++ b/docs/language/ql-handbook/predicates.rst @@ -262,6 +262,10 @@ multiple binding set annotations, for example:: x + 1 = y } + from int x, int y + where y = 42 and plusOne(x, y) + select x, y + Multiple binding sets specified this way are independent of each other. The above example means: - If ``x`` is bound, then ``x`` and ``y`` are bound. - If ``y`` is bound, then ``x`` and ``y`` are bound. diff --git a/docs/language/ql-handbook/queries.rst b/docs/language/ql-handbook/queries.rst index 3f0db3acdf3..1c21482af35 100644 --- a/docs/language/ql-handbook/queries.rst +++ b/docs/language/ql-handbook/queries.rst @@ -83,7 +83,7 @@ For example:: result = x * y } -This predicates returns the following results: +This predicate returns the following results: +---+---+--------+ | x | y | result | @@ -96,8 +96,14 @@ This predicates returns the following results: +---+---+--------+ A benefit of writing a query predicate instead of a select clause is that you can call the -predicate in other parts of the code too. In contrast, the select clause is like an anonymous -predicate, so you can't call it later. +predicate in other parts of the code too. For example, you can call ``getProduct`` inside +the body of a :ref:`class `:: + + class MultipleOfThree extends int { + MultipleOfThree() { this = getProduct(_, _) } + } + +In contrast, the select clause is like an anonymous predicate, so you can't call it later. It can also be helpful to add a ``query`` annotation to a predicate while you debug code. That way you can explicitly see the set of tuples that the predicate evaluates to. diff --git a/docs/language/ql-handbook/types.rst b/docs/language/ql-handbook/types.rst index 1643da2bd7b..c1438d16dca 100644 --- a/docs/language/ql-handbook/types.rst +++ b/docs/language/ql-handbook/types.rst @@ -106,7 +106,7 @@ base types. A class can extend multiple types. See :ref:`multiple-inheritance` below. -To be a valid, a class: +To be valid, a class: - Must not extend itself. - Must not extend a :ref:`final` class. - Must not extend types that are incompatible. (See :ref:`type-compatibility`.) @@ -147,7 +147,11 @@ predicate from the :ref:`above ` class:: 1.(OneTwoThree).getAString() -This call returns the results ``"One, two or three: 1"``. +This call returns the result ``"One, two or three: 1"``. + +The expression ``(OneTwoThree)`` is a :ref:`cast `. It ensures that ``1`` has type +``OneTwoThree`` instead of just ``int``. Therefore, it has access to the member predicate +``getAString()``. Member predicates are especially useful because you can chain them together. For example, you can use ``toUpperCase()``, a built-in function defined for ``string``::