Skip to content

Commit

Permalink
Merge pull request #352 from GerardPaligot/doc_quering
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed Oct 6, 2015
2 parents 59103a5 + bdd20ee commit f82c189
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
21 changes: 21 additions & 0 deletions doc/_jekyll/_data/sidebar_doc.yml
Expand Up @@ -94,3 +94,24 @@ entries:
platform: all
product: all
version: all

- title: Quering source code elements
audience: writers, designers
platform: all
product: all
version: all

items:
- title: Filter
url: /filter.html
audience: writers, designers
platform: all
product: all
version: all

- title: Path
url: /path.html
audience: writers, designers
platform: all
product: all
version: all
1 change: 1 addition & 0 deletions doc/_jekyll/_data/tags_doc.yml
Expand Up @@ -2,3 +2,4 @@ allowed-tags:
- getting-started
- usage
- meta-model
- quering
56 changes: 56 additions & 0 deletions doc/filter.md
@@ -0,0 +1,56 @@
---
title: Filter
tags: [quering]
keywords: quering, query, filter, ast, elements
last_updated: October 5, 2015
---

Spoon aims at giving developers a way to query code elements in
one single line of code in the normal cases. Code query is Spoon
is done in plain Java, in the spirit of an embedded DSL.
The information that can be queried is that of a well-formed typed AST.
For this, we provide the query API, based on the notion of `Filter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/Filter.html)).
A Filter defines a predicate of the form of a `matches` method that
returns `true` if an element is part of the filter.
A Filter is given as parameter to a depth-first search algorithm.
During AST traversal, the elements satisfying the matching predicate are
given to the developer for subsequent treatment.
This table gives an excerpt of built-in filters.

Filter class | Description
-------------|------------
`AbstractFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/AbstractFilter.html)) | defines an abstract filter based on matching on the element types.
`TypeFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/TypeFilter.html)) | returns all meta-model elements of a certain type (e.g. all assignment statements).
`AnnotationFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/AnnotationFilter.html)) | returns all elements annotated with a given annotation type.
`ReturnOrThrowFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/ReturnOrThrowFilter.html)) | returns all elements that ends the execution flow of a method.
`InvocationFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/InvocationFilter.html)) | returns all accesses to a given executable or any executable that overrides it.
`VariableAccessFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/VariableAccessFilter.html)) | returns all accesses to a given variable.
`FieldAccessFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/FieldAccessFilter.html)) | returns all accesses to a given field.
`ReferenceTypeFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/ReferenceTypeFilter.html)) | returns all references of a given type.
`DirectReferenceFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/DirectReferenceFilter.html)) | returns all references to a given element by using reference equality.
`NameFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/NameFilter.html)) | filters elements by name.
`RegexFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/RegexFilter.html)) | filters elements with a regular expression on the element's code.
`CompositeFilter` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/CompositeFilter.html)) | defines a composite filter, which can compose several filters together by using `FilteringOperator` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/visitor/filter/FilteringOperator.html)).

See below a code example about the usage of these filters. Three filters of
them are used. The first returns all AST nodes of type `CtAssignment` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/code/CtAssignment.html)).
The second one selects all deprecated classes. The last one is a user-defined
filter that only matches public fields across all classes.

```java
// collecting all assignments of a method body
list1 = methodBody.getElements(new TypeFilter(CtAssignment.class));

// collecting all deprecated classes
list2 = rootPackage.getElements(new AnnotationFilter(Deprecated.class));

// creating a custom filter to select all public fields
list3 = rootPackage.getElements(
new AbstractFilter<CtField>(CtField.class) {
@Override
public boolean matches(CtField field) {
return field.getModifiers.contains(ModifierKind.PUBLIC);
}
}
);
```
73 changes: 73 additions & 0 deletions doc/path.md
@@ -0,0 +1,73 @@
---
title: Path
tags: [quering]
keywords: quering, query, path, ast, elements
last_updated: October 5, 2015
---

`CtPath` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPath.html))
defines the path to a `CtElement` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/declaration/CtElement.html))
in a model respectively to another element. A `CtPath` can also be used
to make a query to get elements and is based on three concepts:
names of elements, types of elements and roles of code elements.

A role is a relation between two AST nodes, encoded as an AST node field.
For instance, a "then" branch in a if/then/else is a role (and not an node).

To build a path, you have two possibilities: `CtPathBuilder` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html))
and `CtPathStringBuilder` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathStringBuilder.html)).
`CtPathBuilder` defines a fluent api to build your path.
`CtPathStringBuilder` creates a path object from a string according to a
syntax inspired from XPath and CSS selectors.

## CtPathStringBuilder

`CtPathStringBuilder` exposes only one method to build a path from a string.

- `fromString(String)` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathStringBuilder.html#fromString-java.lang.String-))
builds a path from a string representation.

For instance, if we want the first statement in the body of method `foo`, declared
in the class `spoon.test.path.Foo`.

```java
new CtPathStringBuilder().fromString(".spoon.test.path.Foo.foo#body[index=0]");
```

## CtPathBuilder

`CtPathBuilder` exposes the following methods:

- `name(String, String[])` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html#name-java.lang.String-java.lang.String:A...-))
adds a name matcher to the current path.
- `type(Class, String[])` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html#type-java.lang.Class-java.lang.String:A...-))
matches on element of a given type.
- `role(CtPathRole, String[])` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html#role-spoon.reflect.path.CtPathRole-java.lang.String:A...-))
matches on elements by their role (where `CtPathRole` gives all constants supported).
- `wildcard()` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html#wildcard--))
matches only on elements child of current one.
- `recursiveWildcard()` ([javadoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/path/CtPathBuilder.html#recursiveWildcard--))
matches on any child and sub-children.

For instance, if we want all elements named by "toto" and with a default value in
a project. Use `CtPathBuilder` like the example below.

```java
new CtPathBuilder().recursiveWildcard().name("toto").role(CtPathRole.DEFAULT_VALUE).build();
```

The corresponding string syntax would be:

```java
new CtPathStringBuilder().fromString("**.toto#defaultValue");
```

The order in instructions is important and have a meaning. These two pieces of code below have
a different meaning. The first one takes all toto elements in the project. The second takes
the first element named by "toto" at the root of your project and after, makes a search recursively
in your project according to the rest of your path request.

```
new CtPathBuilder().recursiveWildcard().name("toto")
new CtPathBuilder().name("toto").recursiveWildcard()
```

0 comments on commit f82c189

Please sign in to comment.