Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: #322 Quering source code elements tutorial in the spoon website. #352

Merged
merged 1 commit into from
Oct 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions doc/_jekyll/_data/sidebar_doc.yml
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ allowed-tags:
- getting-started
- usage
- meta-model
- quering
56 changes: 56 additions & 0 deletions doc/filter.md
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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()
```