|
Page 5 of 7
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
-
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.
- To bring up the quick query editor, click the dropdown button (
)
to the right of the SemmleCode toolbar button ( ) and select Quick Query.

- 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).

- 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].
- 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.
- 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.
- 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.
|