Use JSIS to Roundup Java Source Information

by Steve Blake

The Java sources that make up your project or enterprise are a valuable asset.  They are a virtual Gold Mine of information just waiting to be tapped.  Static source analysis tools are becoming an increasingly important facet supporting nearly all development methodologies including XP and Agile Programming.  Now JSIS Tools has released a new API called JSIS that gives Java developers a simple but powerful means of parsing Java sources and resolving names to their declarations.

JSIS is the Semantic Interface Specification for JavaTM technology, a de-facto standard Java API that combines the capabilities of a Java Parser, Java Reflection, and a compilation unit manager in one simple package.  The JSIS API provides well defined primitive functionality covering the Java syntax and semantics. Secondary queries layered on top of JSIS provide services for tools in any problem domain.

JSIS extends the semantic capability of Reflection with the syntactic parsing capability of a compiler.  The synergistic result is a simple and easy to use API that offers more semantic functionality than Reflection and more element classification and syntactic source location information than a Java parser. Using JSIS, Java programmers can create high quality semantically aware source code analysis and inspection tools for use on their own projects or to promote for commercial sale and profit.

Written in Java, JSIS is“write once, run anywhere”.  It seamlessly supports Java 1.2, 1.3.x, and 1.4. 

Take a look at the JSIS Javadocs or the JSIS API sources.

 

Java Sources Are Similar to XML Documents

JSIS works much the same way as the well known DOM and SAX parsing models do for XML.  You can view your sources as having a structure similar to XML documents; Java elements each have starting and ending points and are hierarchical.  You can select specific elements as you would with a DOM parser, or you can extend a parser handler just like you would do with a SAX event-driven parser.

JSIS lets you access all the elements of your Java sources including compilation units, declarations, names, statements, expressions, comments and tokens.  It supports analysis of implicit elements such as inherited members.  The exact starting and ending location of each element, line and column numbers define the source span each element occupies. 

While JSIS works in tandem with reflection, it goes beyond reflection by providing expressions and statements and resolving all identifiers and qualified names to their declarations.  A gateway allows you to get reflection objects from JSIS declarations and construct JSIS declaration objects from reflection objects.

Here is a chart comparing JSIS features with Reflection and other Java parsers.

    How JSIS Stacks Up

      JSIS Java Parsers Reflection
    Compilation Units      
      Find by class name Yes   Yes
      Find by source file name Yes Yes  
      Find all in a path Yes    
      Find all in the environment Yes    
    Packages      
      Find by package name Yes   Yes
      Find all in a path Yes    
      Final all in the environment Yes    
      Find subpackages Yes    
    Syntactic Parsing      
      Event driven Parser Yes    
      Element classification Yes    
      Declarations Yes Yes Yes
      Statements Yes Yes  
      Expressions Yes Yes  
      Tokens (commas, brackets, etc) Yes Yes  
      Comments Yes Yes  
      Line numbers and spans Yes    
    Semantic Resolution      
      Class/Interface references Yes   Yes
      Method invocations Yes    
      Field references Yes    
      All identifiers Yes    
      All qualified names Yes    

 

A Herd Of Potential Applications

 JSIS supports the creation of nearly any application that requires static semantic and syntactic information about a Java source, program, or environment.  The following table illustrates just some of the potential tool applications that can be built using JSIS:

Browsing and Navigation Tools

Refactoring Tools

Code Formatting Tools

Code Restructuring and Source Tools

Coding Style and Compliance Tools

Data Flow Analysis Tools

Cross Reference Tools

Dependency Tree Analysis Tools

Design Tools

Document Generation Tools

Invocation Call Tree Analysis Tools

Language-sensitive Editing Tools

Language Translation Tools

Quality Assessment Tools

Thread Analysis Tools

Test-case Generation and Coverage Analysis Tools

Quality, & Complexity Metrics Tools

Reverse Engineering Tools

 

 Sample Application: Finding Unused Declarations

To illustrate how to use JSIS, several small example applications are included with the API bundle.  Take a look at one of them, a program that finds and prints a list of unused declarations including private fields, private methods and constructors, parameters, and local declarations.   It illustrates the typical pattern of many JSIS programs:

  1. JSIS program setup, setting reference parsing and setting the source path

  2. Selecting a compilation unit by name from the environment

  3. Syntactic analysis using the JSIS.Parser class to parse only non-token elements

  4. Semantic analysis to resolve the identifier to its declaration name element

  5. Use of java.util classes with JSIS elements to make lists and sets

  6. Release of compilation unit resource

The main method takes to parameters, the unit name and the source path location:

Unused usage:  java com.JSISTools.Examples.Unused <compilation_unit_qualified_name> <source_path>

For example:  java com.JSISTools.Examples.Unused java.lang.String C:/Java/src

The sources of this sample are presented in a browsable HTML format generated by JTNav, an application built and shipped with JSIS.  You can explore the program by clicking on the links of names that resolve to the declarations.   Start with the class that has the main method: com.JSISTools.Examples.Unused

One of the first things to do is get the compilation unit named in the first argument:

        compUnit = Environment.compilationUnit(args[0]);

Next at line 64 there is an instantiation of the class com.JSISTools.Examples.UnusedParserHandler that extends com.JSISTools.JSIS.ParserHandler and implements the StartElement method:

        UnusedParserHandler handler = new UnusedParserHandler();
        Parser                        parser   = new Parser(handler);

 A new Parser is created and the parse is started:

        parser.parse(compUnit, false);  // false suppresses parse of tokens

StartElement classifies the elements placing the names of the desired declarations like paramters into a list.

      switch (element.kind()) {
      case Declaration.PARAMETER: {
          declarationNamesList.add(((Declaration) element).parameterName());
          break;
        }

Elements that are identifiers are resolved to their declared name:

       Name name = ((Expression) element).referencedName();

Names of declarations that belong to the analyzed compilation unit are added to a set. 

       if (name.enclosingCompilationUnit().equals(currentUnit)) {
          referencedNameSet.add((Name) name);
       }

Later, an unusedNamesList is populated by testing which declaration names are not contained in the referencedNamesSet:

      for (int i = 0; i < declarationNamesList.size(); i++) {
        name = (Name) declarationNamesList.get(i);
        if (!referencedNameSet.contains((Name) declarationNamesList.get(i))) {
          unusedNamesList.addLast(name);
        }
      }

The list is sent to Standard.out.

        System.out.println("Unused Declaration Names: ");
        for (int i = 0; i < unusedNamesList.size(); i++) {
          name = (Name) unusedNamesList.get(i);
          System.out.println("  Line " + name.span().firstLine
                             + " " + name.kindImage() + " " + name.image());
        }

Finally, the compilation unit resources are released, an important step when analyzing lots of units:

        compUnit.release();

 

Conclusion

Give JSIS a try next time you want to prospect for information from your sources.  Many of the things you can do with reflection can be done easily with JSIS.  If you have one source or thousands, JSIS will scale to automate your static analysis requirements.  Visit www.jsistools.com for more information and get a JSIS Personal Evaluation version Free!