Skip to content
18 changes: 9 additions & 9 deletions docs/language/learn-ql/java/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att
anntp.hasQualifiedName("java.lang", "SuppressWarnings")
select ann, ann.getValue("value")

➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/632150601>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/1775658606775222283/>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.

As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``:

Expand All @@ -64,7 +64,7 @@ As another example, this query finds all annotation types that only have a singl
)
select anntp

➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/669220001>`__.
➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/2145264152490258283/>`__.

Example: Finding missing ``@Override`` annotations
--------------------------------------------------
Expand Down Expand Up @@ -122,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano
not overriding.getAnAnnotation() instanceof OverrideAnnotation
select overriding, "Method overrides another method, but does not have an @Override annotation."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1505752756202/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/7419756266089837339/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.

Example: Finding calls to deprecated methods
--------------------------------------------
Expand Down Expand Up @@ -192,13 +192,13 @@ For instance, consider this slightly updated example:
.. code-block:: java

class A {
@Deprecated void m() {}
@Deprecated void m() {}

@Deprecated void n() {
m();
}
@Deprecated void n() {
m();
}

@SuppressWarnings("deprecated")
@SuppressWarnings("deprecated")
void r() {
m();
}
Expand Down Expand Up @@ -235,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress
and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation
select call, "This call invokes a deprecated method."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/665760001>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/8706367340403790260/>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.

Further reading
---------------
Expand Down
12 changes: 6 additions & 6 deletions docs/language/learn-ql/java/call-graph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ We can use the ``Callable`` class to write a query that finds methods that are n
where not exists(Callable caller | caller.polyCalls(callee))
select callee

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/665280012/>`__. This simple query typically returns a large number of results.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/8376915232270534450/>`__. This simple query typically returns a large number of results.

.. pull-quote::

Expand All @@ -97,7 +97,7 @@ Running this query on a typical Java project results in lots of hits in the Java
callee.getCompilationUnit().fromSource()
select callee, "Not called."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/668510015/>`__. This change reduces the number of results returned for most projects.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/8711624074465690976/>`__. This change reduces the number of results returned for most projects.

We might also notice several unused methods with the somewhat strange name ``<clinit>``: these are class initializers; while they are not explicitly called anywhere in the code, they are called implicitly whenever the surrounding class is loaded. Hence it makes sense to exclude them from our query. While we are at it, we can also exclude finalizers, which are similarly invoked implicitly:

Expand All @@ -111,7 +111,7 @@ We might also notice several unused methods with the somewhat strange name ``<cl
not callee.hasName("<clinit>") and not callee.hasName("finalize")
select callee, "Not called."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/672230002/>`__. This also reduces the number of results returned by most projects.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/925473733866047471/>`__. This also reduces the number of results returned by most projects.

We may also want to exclude public methods from our query, since they may be external API entry points:

Expand All @@ -126,7 +126,7 @@ We may also want to exclude public methods from our query, since they may be ext
not callee.isPublic()
select callee, "Not called."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/667290016/>`__. This should have a more noticeable effect on the number of results returned.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/6284320987237954610/>`__. This should have a more noticeable effect on the number of results returned.

A further special case is non-public default constructors: in the singleton pattern, for example, a class is provided with private empty default constructor to prevent it from being instantiated. Since the very purpose of such constructors is their not being called, they should not be flagged up:

Expand All @@ -142,7 +142,7 @@ A further special case is non-public default constructors: in the singleton patt
not callee.(Constructor).getNumberOfParameters() = 0
select callee, "Not called."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/673060008/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/2625028545869146918/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.

Finally, on many Java projects there are methods that are invoked indirectly by reflection. So, while there are no calls invoking these methods, they are, in fact, used. It is in general very hard to identify such methods. A very common special case, however, is JUnit test methods, which are reflectively invoked by a test runner. The CodeQL library for Java has support for recognizing test classes of JUnit and other testing frameworks, which we can employ to filter out methods defined in such classes:

Expand All @@ -159,7 +159,7 @@ Finally, on many Java projects there are methods that are invoked indirectly by
not callee.getDeclaringType() instanceof TestClass
select callee, "Not called."

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/665760002/>`__. This should give a further reduction in the number of results returned.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/2055862421970264112/>`__. This should give a further reduction in the number of results returned.

Further reading
---------------
Expand Down
6 changes: 3 additions & 3 deletions docs/language/learn-ql/java/expressions-statements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ We'll start by writing a query that finds less-than expressions (CodeQL class ``
expr.getRightOperand().getType().hasName("long")
select expr

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/672320008/>`__. This query usually finds results on most projects.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/490866529746563234/>`__. This query usually finds results on most projects.

Notice that we use the predicate ``getType`` (available on all subclasses of ``Expr``) to determine the type of the operands. Types, in turn, define the ``hasName`` predicate, which allows us to identify the primitive types ``int`` and ``long``. As it stands, this query finds *all* less-than expressions comparing ``int`` and ``long``, but in fact we are only interested in comparisons that are part of a loop condition. Also, we want to filter out comparisons where either operand is constant, since these are less likely to be real bugs. The revised query looks like this:

Expand All @@ -57,7 +57,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E
not expr.getAnOperand().isCompileTimeConstant()
select expr

➤ `See this in the query console on LGTM.com <https://lgtm.com/query/690010001/>`__. Notice that fewer results are found.
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/4315986481180063825/>`__. Notice that fewer results are found.

The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself.

Expand Down Expand Up @@ -120,7 +120,7 @@ Now we rewrite our query to make use of these new classes:
not expr.getAnOperand().isCompileTimeConstant()
select expr

➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/1951710018/lang:java/>`__.
➤ `See the full query in the query console on LGTM.com <https://lgtm.com/query/506868054626167462/>`__.

Further reading
---------------
Expand Down
Loading