Partial Program Analysis for Eclipse
PPA for Eclipse produces a typed Abstract Syntax Tree from an arbitrary Java source file.
PPA for Eclipse uses the Eclipse JDT compiler as the frontend and is compatible with the Eclipse
JDT Binding API: the compilation unit is an instanceof
org.eclipse.jdt.core.dom.CompilationUnit
and the type bindings are compatible with the
hierarchy of org.eclipse.jdt.core.dom.IBinding
.
This version supports Java 5 syntax and can take as input 1) a Java source file in a Java project, 2) an arbitrary Java source file taken from the file system, or 3) a snippet of code in a String variable or in a text file.
You can follow the development of PPA on BitBucket and ohloh.
Content
- News
- Download PPA for Eclipse.
- 2-minute Tutorial: Getting a CompilationUnit instance - For Eclipse Gurus
- GUI Tools Tutorial: Using the GUI tools - Try PPA without Programming!
- Complete Tutorial: Using PPA in an Eclipse plug-in - For Eclipse Beginners
- Resources
- Bugs and Feature Requests
- Change log
News
June 29th 2010 - Version 1.2.0 is out! It supports Eclipse 3.6 and brings all the improvements of 1.1.2 such as multi-threaded environment, better support for Java 5 generics and anonymous classes, etc.
Download
The current version of PPA for Eclipse is 1.2.0 and it requires Eclipse 3.6 (Helios). This version is actively maintained: feature requests will be considered.
To download PPA for Eclipse, use the following update site:
http://www.sable.mcgill.ca/ppa/site_1.2.x
To download the current development release (might be unstable), use the following update site:
http://www.sable.mcgill.ca/ppa/site_latest
To download the previous version of PPA for Eclipse, which requires Eclipse 3.5, use the following
update site: http://www.sable.mcgill.ca/ppa/site_1.x
PPA is available under the GNU Lesser General Public License and Eclipse is available under the Eclipse Public License.
2-minute Tutorial
This tutorial shows how to get a typed CompilationUnit instance from a single Java file (potentially referring to other unavailable source files). We only give the high-level details here. For a complete tutorial, see PPA Tutorial.
This example assumes that you are in a plug-in project that imports the two following plug-ins:
org.eclipse.jdt.core
and ca.mcgill.cs.swevo.ppa.ui
. The example also assumes
that the plug-in fragment ca.mcgill.cs.swevo.ppa
is loaded (this is done automatically if you
import jdt.core and you have installed PPA for Eclipse).
All PPA plug-ins include the source code so you can browse the code and the API using Eclipse (either Ctrl-Click on a type or use the type dialog using Ctrl-T).
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Name;
import ca.mcgill.cs.swevo.ppa.PPAOptions;
import ca.mcgill.cs.swevo.ppa.ui.PPAUtil;
public class PPAClient {
// This must be called in an Eclipse plug-in, not in a
// standalone Java application.
public void usePPA() {
// The source file.
File srcFile = new File("/tmp/MyJavaFile.java");
// Obtaining a compilation unit using the default options.
CompilationUnit cu = PPAUtil.getCU(file, new PPAOptions());
// Walk through the compilation unit.
...
// Obtain a name object and the corresponding binding
Name nameNode = ...
IBinding binding = nameNode.resolveBinding();
ITypeBinding typeBinding = nameNode.resolveTypeBinding();
}
}
GUI Tools Tutorial
You can execute PPA on any java source files or code snippets in your Eclipse workspace: PPA will traverse the abstract syntax tree of the java source file and print the type of each node in the console.
These GUI tools enable you to try PPA without writing a single line of code. You can also use this tool to submit a bug report by providing the actual output of PPA and telling us the output you expect.
PPA Tutorial
In this tutorial, you will create an Eclipse plug-in project that analyzes a partial program and that prints the type associated to the nodes of the abstract syntax tree of the program. To invoke the analysis, you will push a button in the main toolbar.
No prior knowledge of Eclipse is required, but you should be familiar with programming language concepts such as type and abstract syntax trees.
- Part 1 - Installing Eclipse and PPA
- Part 2 - Creating an Eclipse plug-in
- Part 3 - Using PPA in the plug-in
- Part 4 - Going Headless (Running your plug-in on the command line, without displaying the Eclipse GUI)
Resources
- Eclipse JDT API javadoc - CompilationUnit and IBinding API Reference
- Page on the Eclipse Java Model - Useful to learn how the various pieces of the Java model connect together
Bugs and Feature Requests
If you have any question or comment about PPA, the documentation or this website, you can contact
Barthélémy at: bart at cs dot mcgill dot ca
.
To fill a bug report or a feature request, please enter an issue report on the PPA bitbucket repository.
Change log
1.2.1
- PPA can now produce bytecode from partial programs. Look at method
PPAUtil.compileCU()
for more info. - To allow PPA to produce bytecode, a lot of small bugs had to be fixed and additional information (e.g., modifiers) had to be inferred. For example, super method and field references are now correctly parsed and inferred.
- Added initial support for a headless version of PPAUtil. If you want to run PPA in a GUI-less
environment, please use
ca.mcgill.cs.swevo.ppa.util.PPACoreUtil
. - Released on June 3rd 2011.
- PPA now works on Eclipse 3.6 (but it no longer works on 3.5).
- The Eclipse 3.6 compiler now correctly recognizes most local variables in anonymous classes.
- Please use the new update site for this new line of development:
http://www.sable.mcgill.ca/ppa/site_1.2.x
- Released on June 29th 2010.
- Fixed a few major bugs related to generics and anonymous classes. Thanks to David Kawrykow for reporting these bugs.
- PPA now correctly sets the isAnnotation flag on types binding. More flags will be set in future releases.
- PPA is now thread safe and can execute multiple parallel requests through PPAUtil. Each request will
be executed in its own Java project. For example, four concurrent requests will create four temporary Java
projects. The maximum number of concurrent requests can be set in the PPA preference page.
- To make a concurrent request, call one of PPAUtil methods with a request name, e.g., PPAUtil.getCU(file, options, "myRequest1");
- You can make multiple calls to PPAUtil using the same request name: PPA then uses the same Java project. This is useful if you want to analyze multiple compilation units from the same partial program without calling the PPAUtil.getCUs(...) method.
- Once you are done, call the PPAUtil.cleanUpAll("myRequest1") method to release the temporary Java project and to make it available for other requests. You do not have to call this method if you close Eclipse between requests.
- If you do not wish to submit a request name, you can call the same PPAUtil methods, e.g., PPAUtil.getCU(file, options). PPA will use the current thread name as the request name. This works well in single threaded program or in programs where the same thread is doing the analysis and the cleanup. These methods also make sure that PPA is backward compatible with previous releases.
- On a decent computer with multiple cores, you will see an improvement if you make parallel requests. For example, on my computer, I could parse twice as many compilation units using four threads vs. one thread. This means though that the performance does not increase linearly with the number of threads.
- This is likely the last release supporting Eclipse 3.5.2. A new release supporting Eclipse 3.6 is likely to be published in early July.
- Released on June 29th 2010.
- Fixed a bug when comparing two types and one of their declaring class is null. Thanks to Yueqi Li for reporting this bug.
- Added inference of array types of local variables in anonymous classes.
- Warning: due to an Eclipse compiler limitation, the type of a local variable in an anoymous class is not propagated to the uses of that variable. Consequently, the type of the variable will often be UNKNOWN. I have no plan to implement a workaround for the near future because this would require significant development (there is no clean and easy way of doing this).
- Released on December 11th 2009.
- Added support for Eclipse 3.5 (but had to drop support for Eclipse 3.4).
- Finally added support for the default package.
- Released on October 20th 2009.
- Fixed a bug with compatible types and null (e.g., null and Object should match when searching for a method).
- Fixed a bug where the container's type of a field was not properly inferred. Thanks to Puneet Kapur for reporting this bug.
- Made wrong field case consistent: when PPA encounters an impossible field (e.g., String.foo), the field is still created as being contained by String, but String does not contain foo. This is a rare case (uncompilable code or jdk class shadowing), but in the future, I plan to let the user decides the behaviour for such a case through an option in PPAEngine.
- Added inference support for super method invocation.
- Fixed another bug related to fully qualified name.
- Fixed a bug that incorrectly inferred the type of a variable that was declared with its fully qualified type. Thanks to Ekwa Duala-Ekoko for reporting this bug.
- Added constructor inference strategy and constructor member inference.
- Added array access inference strategy.
- Constructors are correctly handled now: the name of a constructor is no longer <init>, but the name of the class. <init> is still used for anonymous classes, but this name is provided by Eclipse and not PPA. The name of constructors should now be consistent with the Eclipse API.
- Changed a warn to an info notification: the log file should be shorter now because it only reports statements with a log level >= warning.
- PPA now handles Enum types (i.e., methods like name() are correctly resolved and NPE are no longer thrown).
- UI Actions (e.g., Run PPA (file)) no longer hangs with large files: a progress monitor was added to address the issue. Thanks to Joel Ossher for reporting these bugs.
- Added the missing log4j properties file to the build. Thanks to Joel Ossher for reporting this bug.
- Added the following inference strategies: binary, unary, array index, condition.
- Bug fixes.
- Qualified Names bug fixes.
- More support for generics.
- First release of PPA.
- Syntax Disambiguation
- Support for single source file analysis mode (no global mode for now).
- Support for enabling/disabling syntax disambiguation, type inference and method binding passes.
- Basic inference strategies: assignment, return, method binding
- Basic support for Code snippets
- Basic support for Java 1.5