Basic Launcher

The Spoon Launcher (JavaDoc) is used to create the AST model of a project. It can be as short as:

CtClass l = Launcher.parseClass("class A { void m() { System.out.println(\"yeah\");} }");

The Launcher is highly configurable:

Launcher launcher = new Launcher();

// path can be a folder or a file
// addInputResource can be called several times
launcher.addInputResource("<path_to_source>"); 

// if true, the pretty-printed code is readable without fully-qualified names
launcher.getEnvironment().setAutoImports(true); // optional

// if true, the model can be built even if the dependencies of the analyzed source code are not known or incomplete
// the classes that are in the current classpath are taken into account
launcher.getEnvironment().setNoClasspath(true); // optional

launcher.buildModel();
CtModel model = launcher.getModel();

Maven Launcher

The Spoon MavenLauncher (JavaDoc) is used to create the AST model of a Maven project. It automatically infers the list of source folders and the dependencies from the pom.xml file. This Launcher handles multi-module Maven projects.

// the second parameter can be APP_SOURCE / TEST_SOURCE / ALL_SOURCE
MavenLauncher launcher = new MavenLauncher("<path_to_maven_project>", MavenLauncher.SOURCE_TYPE.APP_SOURCE);
launcher.buildModel();
CtModel model = launcher.getModel();

// list all packages of the model
for(CtPackage p : model.getAllPackages()) {
  System.out.println("package: "+p.getQualifiedName());
}
// list all classes of the model
for(CtType<?> s : model.getAllTypes()) {
  System.out.println("class: "+s.getQualifiedName());
}

About the classpath

Spoon analyzes source code. However, this source code may refer to libraries (as a field, parameter, or method return type). There are two cases:

  • Full classpath: all dependencies are in the JVM classpath or are given to the Laucher with launcher.getEnvironment().setSourceClasspath("<classpath_project>"); (optional)
  • No classpath: some dependencies are unknown and launcher.getEnvironment().setNoClasspath(true) is set.

This has a direct impact on Spoon references. When you're consider a reference object (say, a TypeReference), there are three cases:

  • Case 1 (code available as source code): the reference points to a code element for which the source code is present. In this case, reference.getDeclaration() returns this code element (e.g. TypeReference.getDeclaration returns the CtType representing the given java file). reference.getTypeDeclaration() is identical to reference.getDeclaration().
  • Case 2 (code available as binary in the classpath): the reference points to a code element for which the source code is NOT present, but for which the binary class is in the classpath (either the JVM classpath or the --source-classpath argument). In this case, reference.getDeclaration() returns null and reference.getTypeDeclaration returns a partial CtType built using runtime reflection. Those objects built using runtime reflection are called shadow objects; and you can identify them with method isShadow. (This also holds for getFieldDeclaration and getExecutableDeclaration)
  • Case 3 (code not available, aka noclasspath): the reference points to a code element for which the source code is NOT present, but for which the binary class is NOT in the classpath. This is called in Spoon the noclasspath mode. In this case, both reference.getDeclaration() and reference.getTypeDeclaration() return null. (This also holds for getFieldDeclaration and getExecutableDeclaration)

Declaring the dependency to Spoon

Maven

<dependency>
    <groupId>fr.inria.gforge.spoon</groupId>
    <artifactId>spoon-core</artifactId>
    <version>5.9.0</version>
</dependency>

Gradle

compile 'fr.inria.gforge.spoon:spoon-core:5.9.0'