Article Index
Quick Guide
Setting the License
Running the Standard Analysis
Viewing Results
Writing Your Own Analysis
Organizing Your Analyses
Further Help

Writing Your Own Analysis

Unlike other analysis tools, you can easily write your own analyses in SemmleCode. All analyses in SemmleCode are .QL queries. which allow you to modify the ones that come with SemmleCode as well as writing your own.

You can use the Quick Query Editor for single-use queries, or create and edit your own query file using the .QL Query Editor. Queries are written in .QL, an object-oriented query language, and SemmleCode provides an extensive library to support custom analyses. Here we give a quick overview of the Quick Query editor for writing custom code queries.

from-where-select

.QL queries take the general form from-where-select. The from clause contains a declaration of variables that are going to be used in the query, the where clause contains the conditions that must be satisfied by the results of the query and the select clause specifies which elements are to be part of the query result.

The following query finds all public fields that are not final, and each row in the result contains the package of the field's declaring type, the declaring type and then the field itself.

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

Quick Query Editor

The Quick Query editor allows you to write throwaway queries, useful when writing small queries to explore the structure of a project.

Using the Quick Query Editor

  1. Before writing your query, you may want to change the active scope to change the set of projects the query will be run on. To do this, select one or more projects in the Package Explorer, right-click and select SemmleCode > Set as Active Scope.

  2. To bring up the quick query editor, click the dropdown button () to the right of the SemmleCode toolbar button () and select Quick Query.

  3. You can now start typing your custom query into the editor. The editor itself supports syntax highlighting, on-the-fly syntax checking, autocompletion and code browsing (using Ctrl-click on a program element to jump to its declaration).

  4. After writing your query, you can select the visualization used to display the results. The visualization types can be selected using the buttons on the lower-left portion of the quick query dialog.



    SemmleCode supports the following display types, some of which require the columns of the result to be of a certain form:
    • A tree (). Any result can be shown as a tree, with each column forming a level of the tree.
    • A table (). Any result can be shown as a table.
    • A list of problems (). Problem lists require the results to be of the form <Entity>, String.
    • A chart () . A chart requires the result to be of the form <Entity>, number, number.
    • A graph () . A graph requirs the result to be of the form <Entity>, <Entity>.
    • A treemap () . A treemap requires the result to be of the form <Entity>+, number, [number].
  5. Once you have completed writing the query, click the Run button () to on the upper-right hand portion of the dialog to run the query. The corresponding query result entry should then appear on the Results View. You can double-click the query result entry () to re-edit and re-run the query.
  6. If you wish to recover the last quick query, click the Restore Query button () button on the upper-right portion of the quick query dialog.
  7. You may also save the quick query to a file for further editing, or inclusion in a .QL analysis. Click the Save Query button () on the upper-right portion of the quick query dialog. You can then edit the saved query using the .QL Query Editor.

Example Queries

You can try out and modify these sample queries to give you a taste of how to start writing custom queries. You can just cut and paste the queries into the editor, making sure not to overwrite the import default declaration at the start of the editor.

Public Non-Final Fields

The following query finds public non-final fields, which may inadvertently expose the implementation details of a class. This query is best displayed as a tree ().

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

Hub Types

Hub types are types that are used by a large number of classes (i.e. have high afferent coupling) and also use a large number of classes (i.e. have high efferent coupling). These types are important in that they are more likely to be affected by changes and in turn are likely to affect many dependent types when they are changed. When viewed as a treemap (), classes are displayed as boxes, the size of which is proportional to its afferent coupling, and colored according to its efferent coupling. When displayed, large red boxes represent the hub types.

from RefType t
where t.fromSource()
select t.getPackage(), 
       t,
       t.getMetrics().getAfferentCoupling() as AfferentCoupling, 
       t.getMetrics().getEfferentSourceCoupling() as EfferentCoupling
order by AfferentCoupling desc 

Ant Target Dependencies

This query finds the dependencies between targets in an ant file. This sort of information is usually difficult to glean directly from an ant file due to their size and lack of structure. This query is best displayed as a graph ().

from MainAntTarget t, MainAntTarget dep
where dep = t.getADependency()
select t, dep

Calls to System.exit

Calls to System.exit would usually cause problems in most modern programs, which usually run on some framework. The following query finds calls to System.exit and is best displayed as a list of problems ().

from Method m, Method sysexit, Class system
where m.getACall() = sysexit
  and sysexit.hasName("exit")
  and sysexit.getDeclaringType() = system
  and system.hasQualifiedName("java.lang", "System")
  and m.fromSource() 
  and not m.hasName("main")
select m, "This method calls System.exit(...)"

You can try some more example queries taken from SemmleCode's standard analysis. These will give you a feel of what is possible with SemmleCode and get you started on writing your own custom project-specific queries.

Using the .QL Query Editor

Once you are ready to start writing more substantial queries that will be part of your own projects, you can start using the .QL Query Editor.

Create a new .QL Query by clicking File > New > Other... > Semmle .QL > .QL Query. You can now edit the query using the .QL editor, which works the same way as the Quick Query Editor.

For more detailed help on how to create a new query and edit a .QL query using the .QL Query Editor see the SemmleCode User Guide (Help > Help Contents > SemmleCode User Guide).

You can also look at a more detailed tutorial on the .QL language in the .QL tutorial.

The next section in the tutorial will show you how to organize your collection of queries into an analysis.