The Artima Developer Community
Sponsored Link

Artima Developer Spotlight Forum
How Code Queries Improve Software Quality

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Elnar Hajiyev

Posts: 5
Nickname: semhq1
Registered: Jun, 2007

How Code Queries Improve Software Quality Posted: Jul 17, 2007 7:58 AM
Reply to this message Reply
Advertisement

Many coding conventions have important consequences for code quality. Not all coding conventions can be enforced via APIs, and some have to be treated as just conventions that, however, have to be enforced across a project's entire code base.

For instance, the team I work with uses the Polyglot compiler framework. In Polyglot, a coding convention is that every instance of a tree node must be created via a factory. Call a tree node constructor directly from client code, and you will have extensibility problems later on. How do you enforce this convention?

We could implement a special code checker, but that would seem like too much of a distraction from our main job. Still, every time a new team member introduces the same bug because we forgot to tell him about Polyglot's coding convention, we sure wish the automatic code check had been there.

Surely, this story will resonate with many of you reading this—the framework may be different, but every developer encounters the problem of enforcing coding conventions that are specific to an API or a project. For highly popular frameworks, such as Java EE, there are off-the-shelf style checkers, such as FindBugs. But what do you do when your needs are more specialized or even ad hoc, and the investment of building a specialized tool seems too much an undertaking?

Enter SemmleCode

A new solution to this problem is an Eclipse plugin called SemmleCode. A freely available tool, SemmleCode is developed by startup from Oxford, UK, as a way to demonstrate their query technology that can be applied to any structured data, such as source code. SemmleCode has built its own developer community, and most new features are driven by the tool's users.

In SemmleCode, the tasks of checking code for metrics, finding bugs, or for enforcing coding conventions, are done code queries, which are similar to database-style queries. Query results can be visualized in many different ways, including graphs and various types of charts.

SemmleCode stores an Eclipse project's relevant data in a relational database. Once a database is set up with use for the project, you can write queries to run the code style checks you need for the project. SemmleCode ships with many pre-defined queries for common tasks, and those pre-defined queries can be launched via the run menu of Eclipse.

SemmleCode's ability to allow a developer to issue queries against a code base to discover relevant code metrics and style elements is sometimes referred to as "application intelligence," "application mining," or "software portfolio management." SemmleCode differs from other application intelligence tools in that it directly facilitates agile development: all team members, regardless of their role, can extract the information they need from the code base, and in the format they need that information. SemmleCode achieves that agility with an object-oriented query language, .QL.

A Java EE Example

To illustrate .QL, consider the requirement of a Java EE entity bean that it must have a public constructor with no parameters. To find classes that violate that rule, you can use the following QL query:

from EntityBean ebean
where not exists (Constructor c | 
                   c.getDeclaringType()=ebean and
                   c.hasModifier("public") and 
                   c.hasNoParameters())
select ebean, ebean.toString() + " must contain a public " +
                          "constructor with no parameters"

The results of this query are then displayed in the Eclipse problems view, and also as error markers in the source itself.

A Metrics Example

Suppose you are considering whether to replace the use of org.apache.roller.business.* with a completely new implementation. To assess the impact of that proposed change, it is useful to know what types have strong dependencies on the packages that are about to be replaced. To find types that have more than 40 dependencies on those packages—calls, references to types, etc.—you can execute the query:

from RefType t, int n
where n = count(RefType s, Reason r | 
                depends(t,s,_,r) and
                s.getPackage().getName().matches("org.apache.roller.business%"))
      and
      n > 40
select t,n order by n desc

The results can be displayed in a bar chart; clicking on a bar then takes the user to the corresponding type. Note that it would be tough to find this information with a tool where the supported code metrics are hard-wired. Because of it's query language, SemmleCode can present information tailored to the exact questions you have about your codebase.

Generic Queries

Let's now return to the example problem mentioned at the beginning of this article. It is actually a very generic pattern: a factory is introduced for a certain product (here tree nodes), and all instances of the product must be created by that factory and in no other way.

We only need to specify what our factory is, and what type of objects that factory is supposed to be producing. In Polyglot, a factory is any implementation of the polyglot.ast.NodeFactory interface, and the product of that factory is any implementation of the the polyglot.ast.Node interface. In SemmleCode's .QL, this is expressed in the following three steps:

  1. Define the notion of an ASTNode

    class ASTNode extends RefType {
       ASTNode() { this.getASupertype+().
                         hasQualifiedName("polyglot.ast","Node") 
       }
    }
    
  2. In a similar manner, define the notion of an ASTFactory. This time we add an additional method, too: getAViolation(). The purpose of this method is to look for an AST constructor call which does not occur inside an AST factory, and which is also not a super or this constructor call from an AST constructor.

    class ASTFactory extends RefType {
       ASTFactory() { this.getASupertype+().
                             hasQualifiedName("polyglot.ast","NodeFactory")
       }
    
       ConstructorCall getAViolation() {
          result.getType() instanceof ASTNode and
          not(result.getCaller().getDeclaringType()
                                   instanceof ASTFactory) and
          not(result instanceof SuperConstructorCall or
              result instanceof ThisConstructorCall)
       }
    }
    
  3. Having built these classes, we can now write the final query:

    from ASTFactory f,Call c 
    where c = f.getAViolation()
    select c, "use factory instead"
    

    This query will report a warning whenever a constructor call is found outside the factory. None of the types or methods used in the above examples are hardwired into the tool. All of them are also customisable definitions in the standard library shipped with the SemmleCode.

What do you think of Semmle's query-based approach to code analysis?

Topic: How Code Queries Improve Software Quality Previous Topic   Next Topic Topic: OpenDS 0.9 Provides Java Implementation of LDAP, DSML

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use