SemmleCode Introductory Tutorial

Article Index
SemmleCode Introductory Tutorial
Loading Code
Writing Queries
Packaged Queries
Viewing Results
Saving Queries

Viewing query results

SemmleCode offers seven different ways of viewing the results of your queries, namely as:

  • a hierarchy, in SemmleCode's own Tree result window
  • an information item in the Eclipse Problems window
  • a warning in the Eclipse Problems window
  • an error in the Eclipse Problems window
  • a pie chart in its own window
  • a bar chart in its own window
  • a table
  • an interactive graph in its own window

However, not every type of view makes sense for every query, so there are some restrictions that we shall review below.

Sorting results

For any type of view, you can order the results using an order by clause. Say you wish to sort all reference types in descending order of the number of methods they contain:

from RefType t, int i
where i = count(Method m | m.getDeclaringType() = t)
select t, i order by i desc

When you then view the result as a bar chart (by selecting ; as a bar chart), you get a nicely descending picture instead of a jumble:

If you prefer ascending order instead, just replace the desc modifier at the end of the query by asc (for ascending). In fact, if you simply leave off desc, the default for order by is ascending.

Tree results

Tree results are displayed whenever a query is executed via the query-as-a-tree () button. The tree result view is useful for navigating your code.

The hierarchical order of display is determined by the list of selected items in the query: the leftmost item comes at the top of the hierarchy. For example, one might employ a coding convention that all field that are public must also be final. In order to find violations of this rule you might write:

from Field f
where f.hasModifier("public") 
      and
      not f.hasModifier("final")
select f.getDeclaringType().getPackage(), 
       f.getDeclaringType(),
       f

This results in the display (expand a tree node by clicking on the icon next to it):

)

The strings shown are computed via the toString method. The icons are determined via the iconPath method. You can override these in your own classes, to display them in some special way. An example of that can be found in the section on methods in the "Object-Oriented Code Queries" tutorial. With SemmleCode, it's easy to display your query results tailored to your own taste and circumstances.

Problem view results

You may wish to flag the results of certain queries for the programmer's attention, treating them as Eclipse-generated messages. To do that, rewrite our earlier coding convention query for public non-final fields as

from Field f
where f.hasModifier("public") 
      and
      not f.hasModifier("final")
      and
      f.getDeclaringType().getPackage().getName().matches("org.jhotdraw%")
select f, ("consider defining accessor methods for field: " + f.toString())

Note that we selected just two things this time round: the field f itself, plus a string that is the message we wish to convey.

The query-as-problems drop-down menu (labelled ) is enabled in the Quick query window after you have entered this last query. Select as warnings from the drop down list that you obtain by clicking on the downward arrow.

When the query is completed, its results are shown under Warnings in the Problems view of Eclipse. When you click on any of those results, it will take you to the relevant location in the source.

Note that the information item is displayed in the margin there as well: the use of SemmleCode queries seamlessly integrates with existing Eclipse features.

If you wish to remove the info/warnings/errors reported by Semmle, both from the problem view and from the source, right click on the problem view. Select Clear SemmleCode results and you have a fresh copy to run some new queries!

In summary, in order to display query results via the Eclipse Problems view, you need a query that returns a program element and a string, but nothing else.

Warning and Error results work just like information items, except that you select a different item under the Query as problems drop-down menu.

Chart results

If you have a query where two items are selected and one is numerical, you can display the results as a chart.

For instance, define the size of a type to be the number of callables (constructors or methods) declared in that type. Now, for each such size in the project, we'd like to know how many types have the same size. Viewed as a piechart, this gives some indication of the overall complexity of the project, and how well it has been factored into types.

Before reading on, imagine writing that sort of query directly in SQL. Does your head explode? Ours does, but fear not, in .QL it's very easy:

predicate size(RefType t, int i) {
     t.fromSource()
     and
     i = count(Callable c | c.getDeclaringType() = t)
}

from int i
where exists(RefType t | size(t,i))
select i, count(RefType s | size(s,i)) order by i

We start by defining a new classless predicate size(t,i) that relates a type t to its size i. Our query then ranges over all integers i that occur as the size of some type t. For each such i we report the number of types s that have size i.

Press the Query-as-chart button at the top of the quick query view: you can chose to view the results as a pie chart or a bar chart. Here is the pie view:

Chart results can also be exported as an image in .png or .eps format. Right-click on the chart view and select Export and the format of your choice.

Table Results

The results of a query can also be displayed in a table format, which is especially useful as an alternative way to view tree or chart queries.

The following simple query selects all methods from source, along with its return type, declaring type, and the package of the declaring type.

from Method m
where m.fromSource()
select m.getDeclaringType().getPackage() as package,
       m.getDeclaringType() as decltype,
       m as method,
       m.getType() as rettype

Copy the query to the Quick Query window and press the query-as-table button () to view the results in table form.

The table view shows the results with one column for each of the elements in the select clause of the query. You can sort on a column by clicking that column's header in the tree view. Note that names of the columns correspond to the names given in the query and can be changed by changing the query accordingly.

Double-clicking on a cell in the table that is a program element allows you to navigate to the location of that program element in the code. This alternative navigation view allows you to quickly jump to program elements without expanding them as in the tree view.

Any query can be displayed as a table.

Graph results

You can also display results as a graph, and this is particularly helpful to display relationships between program elements. Queries that select two entities of the same type can be displayed as a graph. To be more specific, graph queries require that a query select (type, type, String).

Let's define a simple query that finds call relationships between packages

from Package caller, Package callee
where caller.getARefType().getACallable().calls(callee.getARefType().getACallable()) and
      caller.getName().matches("org.jhotdraw.samples%") and
      callee.getName().matches("org.jhotdraw%")
select caller, callee, "calls"

The query selects packages caller and callee where there exists a type in caller that calls a callable in callee. The third entry in the selection is a string that is used to label the arrow that will connect the two packages in the graph. You can then display this as a graph using the Query as graph button ()

This should produce a graph similar to the one below:

The graph is rather dense and difficult to understand. Fortunately, the graph view has several features that make graph comprehension much easier.

The first method is to change the layout of the graph. The graph view has several graph layouts that could make the graph clearer. Right-click on the graph view and select the layout you want in the Layout item of the right-click menu. For this tutorial, pick the Circular layout.

To navigate the graph, you can change the editing mode of the graph. To do this, right click and select the editing mode you wish under the Edition mode menu item in the right-click menu. For this tutorial, pick the transforming editing mode. This allows you to click-drag the graph. You can also zoom in and zoom out the graph using the mousewheel.

The picking editing mode allows to to pick nodes and edges in the graph. To go into picking mode, bring up the right click menu again and select Picking in the Edition mode menu item. You can click on nodes and edges to select them. You can also click and drag on nodes while in picking mode to move them in the graph.

You can filter the set of nodes and edges by highlighting only the neighbors of the currently selected set of nodes. To do this, bring up the right-click menu and select Highlight selection's neighbors.

This would fade the other nodes that are not immediately connected to the current set of selected nodes.

There is one final editing mode that could be useful. Select the Layout magnifying editing mode in the right-click menu.

This brings up a magnifying lens that you can drag around the graph to highlight certain nodes.

That's it, you are ready. Go to our forums to share your queries, interact with other semmle users and ask for new SemmleCode features. We would also appreciate it, if you could take one minute to rate this plugin.

from YourCode select ... all you want to know!


You can also continue to learn how to save your queries so you can run them later. Go to the next page which gives a short tutorial on how to save and manage queries.