diff --git a/docs/language/learn-ql/advanced/advanced-ql.rst b/docs/language/learn-ql/advanced/advanced-ql.rst index 051d649cf420..d612c08b7cf7 100644 --- a/docs/language/learn-ql/advanced/advanced-ql.rst +++ b/docs/language/learn-ql/advanced/advanced-ql.rst @@ -10,6 +10,4 @@ Advanced QL Topics on advanced uses of QL. These topics assume that you are familiar with QL and the basics of query writing. -- :doc:`Choosing appropriate ways to constrain types ` -- :doc:`Determining the most specific types of a variable ` - :doc:`Monotonic aggregates in QL ` diff --git a/docs/language/learn-ql/advanced/constraining-types.rst b/docs/language/learn-ql/advanced/constraining-types.rst deleted file mode 100644 index 3a8d2e76637f..000000000000 --- a/docs/language/learn-ql/advanced/constraining-types.rst +++ /dev/null @@ -1,73 +0,0 @@ -Constraining types -================== - -Type constraint methods ------------------------ - -.. pull-quote:: - - Note - - The examples below use the CodeQL library for Java. All libraries support using these methods to constrain variables, the only difference is in the names of the classes used. - -There are several ways of imposing type constraints on variables: - -- Use an ``instanceof`` test, for example: - - .. code-block:: ql - - import java - - from Type t - where t instanceof Class - select t - -- Use a cast, for example: - - .. code-block:: ql - - import java - - from Type t - where t.(Class).getASupertype().hasName("List") - select t - -- Set the variable equal to another variable with the required type using exists, for example: - - .. code-block:: ql - - import java - - from Type t - where exists(Class c | - c = t - and c.getASupertype().hasName("List") - ) - select t - -- Pass the variable to a predicate that expects a variable of the required type, for example: - - .. code-block:: ql - - import java - - predicate derivedFromList(Class c) { - c.getASupertype().hasName("List") - } - - from Type t - where derivedFromList(t) - select t - -All of these methods constrain the variable ``t`` to have values of type ``Class``. - -Choosing between the methods ----------------------------- - -These methods have advantages and disadvantages depending on the extent to which you need to work with the variable as the new type: - -- ``instanceof`` only checks that the variable has the required type. -- A cast gives you one, and only one, access to the variable as the new type. -- Creating a new variable with ``exists`` or a predicate parameter allows repeated access to the variable as the new type. - - - Note that due to the ability to overload predicates in a class, predicates that belong to a class must be supplied with arguments of the exact type they specify, and so this technique will not work in that situation. diff --git a/docs/language/learn-ql/advanced/determining-specific-types-variables.rst b/docs/language/learn-ql/advanced/determining-specific-types-variables.rst deleted file mode 100644 index 7deadde39c97..000000000000 --- a/docs/language/learn-ql/advanced/determining-specific-types-variables.rst +++ /dev/null @@ -1,28 +0,0 @@ -Determining the most specific types of a variable -================================================= - -It is sometimes useful to be able to determine what types an entity has -- especially when you are unfamiliar with the library used by a query. To help with this, there is a predicate called ``getAQlClass()``, which returns the most specific QL types of the entity that it is called on. - -This can be useful when you are not sure of the most precise class of a value. Discovering a more precise class can allow you to cast to it and use predicates that are not available on the more general class. - -Example -------- - -If you were working with a Java database, you might use ``getAQlClass()`` on every ``Expr`` in a callable called ``c``: - -**Java example** - -.. code-block:: ql - - import java - - from Expr e, Callable c - where - c.getDeclaringType().hasQualifiedName("my.namespace.name", "MyClass") - and c.getName() = "c" - and e.getEnclosingCallable() = c - select e, e.getAQlClass() - -The result of this query is a list of the most specific types of every ``Expr`` in that function. You will see multiple results for some expressions because that expression is represented by more than one type. - -For example, ``StringLiteral``\ s like ``"Hello"`` in Java belong to both the ``StringLiteral`` class (a specialization of the ``Literal`` class) and the ``CompileTimeConstantExpr`` class. So any instances of ``StringLiteral``\ s in the results will produce more than one result, one for each of the classes to which they belong. diff --git a/docs/language/learn-ql/writing-queries/debugging-queries.rst b/docs/language/learn-ql/writing-queries/debugging-queries.rst index 68bb1bae9b77..b0b033213540 100644 --- a/docs/language/learn-ql/writing-queries/debugging-queries.rst +++ b/docs/language/learn-ql/writing-queries/debugging-queries.rst @@ -62,6 +62,28 @@ is preferred over:: From the type context, the query optimizer deduces that some parts of the program are redundant and removes them, or *specializes* them. +Determine the most specific types of a variable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are unfamiliar with the library used in a query, you can use CodeQL to determine what types an entity has. There is a predicate called ``getAQlClass()``, which returns the most specific QL types of the entity that it is called on. + +For example, if you were working with a Java database, you might use ``getAQlClass()`` on every ``Expr`` in a callable called ``c``: + +.. code-block:: ql + + import java + + from Expr e, Callable c + where + c.getDeclaringType().hasQualifiedName("my.namespace.name", "MyClass") + and c.getName() = "c" + and e.getEnclosingCallable() = c + select e, e.getAQlClass() + +The result of this query is a list of the most specific types of every ``Expr`` in that function. You will see multiple results for expressions that are represented by more than one type, so it will likely return a very large table of results. + +Use ``getAQlClass()`` as a debugging tool, but don't include it in the final version of your query, as it slows down performance. + Avoid complex recursion ~~~~~~~~~~~~~~~~~~~~~~~