CtPath
(javadoc)defines the path to aCtElement
(javadoc)in a model, similarly to XPath for XML. For example,.spoon.test.path.testclasses.Foo.foo#body#statement[index=0]
represents the first statement of the body of method foo.ACtPath
is based on: names of elements (e.g.,foo
), and roles of elements with respect to their parent (e.g.,body
).A role is a relation between two AST nodes.For instance, a “then” branch in an if/then/else is a role (and not a node). All roles can be found inCtRole
. In addition, each getter or setter in the metamodel is annotated with its role.
Evaluating AST paths
Paths are used to find code elements, from a given root element.
path=newCtPathStringBuilder().fromString(".spoon.test.path.testclasses.Foo.foo#body#statement[index=0]");List<CtElement>l=path.evaluateOn(root)
Creating AST paths
From an existing element
MethodgetPath
inCtElement
returns a path
CtPathpath=anElement.getPath();
From a string
CtPathStringBuilder
(javadoc), creates a path object from a string according to the following syntax:
.<name>
which denotes a child element with namename
, e.g.,.fr.inria.Spoon
(the fully qualified name)#<role>
which denotes all children onCtRole
role
statements,#body#statement[index=2]#else
is the else branch of the second statement of a method bodyname=<somename>
- filter which accepts only elements withsomename
. E.g.,#field[name=abc]
signature=<somesignature>
- filter which accepts only methods and constructors with signaturesomesignature
.- Example of method signature:
#method[signature=compare(java.lang.String,java.lang.String)]
- Example of constructor signature:
#constructor[signature=(int)]
index=<idx>
- fitler which accepts only idx-th element of the List. The first element has index 0. The fifth type member in a class#typeMember[index=4]
From the API
The low-levelCtPathBuilder
(javadoc) defines a fluent API to build your path:
name(String, String[])
(javadoc)adds a name matcher to the current path.type(Class, String[])
(javadoc)matches on element of a given type.role(CtPathRole, String[])
(javadoc)matches on elements by their role (whereCtPathRole
gives all constants supported).wildcard()
(javadoc)matches only on elements child of current one.recursiveWildcard()
(javadoc)matches on any child and sub-children.
For instance, if we want all elements named by “toto” and with a default value ina project. UseCtPathBuilder
like the example below.
CtPathp1=newCtPathBuilder().recursiveWildcard().name("toto").role(CtPathRole.DEFAULT_VALUE).build();// equivalent toCtPathp2=newCtPathStringBuilder().fromString(".**.toto#default_value").build();// takes all elements named "toto" in the project.newCtPathBuilder().recursiveWildcard().name("toto")// takes the first element named "toto", a package or a class in the default package, at the root of your project.newCtPathBuilder().name("toto").recursiveWildcard()