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

review: feat: Spoon CtRole based attributes access #1582

Merged
merged 14 commits into from
Nov 10, 2017
22 changes: 19 additions & 3 deletions doc/filter.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
---
title: Filter
title: Navigation and Query
tags: [quering]
keywords: quering, query, filter, ast, elements
---

Spoon gives developers a way to query code elements.

Getters
-------

All elements provide a set of appropriate getters to get the children of an element.


```java
methods = ctClass.getMethods();
```

In addition, there exists a generic getter based on the role played by an element with respect to its parent. See CtRole for a complete list of roles.

```java
methods = ctClass.getValueByRole(CtRole.METHOD);
```


Filters
-------
Expand Down Expand Up @@ -120,4 +136,4 @@ It is faster then `query.list().get(0)`, because query engine does not collect o
```java
// returns first deprecated element
CtElement firstDeprecated = rootPackage.filterChildren(new AnnotationFilter(Deprecated.class)).first();
```
```
17 changes: 17 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,21 @@ <E extends CtElement> List<E> getAnnotatedChildren(
* Clone the element which calls this method in a new object.
*/
CtElement clone();

/**
* @return a a single value (eg a CtElement), List, Set or Map depending on this `element` and `role`. Returned collections are read-only.
* @param the role of the returned attribute with respect to this element.
*
* For instance, "klass.getValueByRole(CtRole.METHOD)" returns a list of methods.
*
* See {@link spoon.reflect.meta.impl.RoleHandlerHelper} for more advanced methods.
*/
<T> T getValueByRole(CtRole role);

/**
* Sets a field according to a role.
* @param the role of the field to be set
* @param value to be assigned to this field.
*/
<E extends CtElement, T> E setValueByRole(CtRole role, T value);
}
43 changes: 43 additions & 0 deletions src/main/java/spoon/reflect/meta/ContainerKind.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (C) 2006-2017 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.reflect.meta;

/**
* Defines kind of container, which is used in an attribute of Spoon model
*/
public enum ContainerKind {
/**
* it is a single value field
* Example: CtClassImpl.simpleName
*/
SINGLE,
/**
* It is a list of values
* Example: CtClassImpl.typeMembers
*/
LIST,
/**
* It is a set of values
* Example: CtPackageImpl.types
*/
SET,
/**
* It is a map&lt;String, T&gt; of values
* Example: CtAnnotationImpl.elementValues
*/
MAP;
}
87 changes: 87 additions & 0 deletions src/main/java/spoon/reflect/meta/RoleHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Copyright (C) 2006-2017 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.reflect.meta;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import spoon.reflect.path.CtRole;

/**
* Enables client code to get and set a field based on a role for a CtElement.
*
* One obtains instances of {@link RoleHandler} using the methods of {@link spoon.reflect.meta.impl.RoleHandlerHelper}.
*
* There is one role handler per role of {@link CtRole}, they are set by {@link spoon.reflect.meta.impl.RoleHandlerHelper}.
*/
public interface RoleHandler {
// the main methods, responsible to get and set the field corresponding to this role
/**
* @param element a element from which the value will be get for this role
* @return a value of the element on the role defined by {@link #getRole()}
*/
<T, U> U getValue(T element);
/**
* @param element a element whose value will be set for this role
* @param value new value, which will be assigned to the element's attribute defined by role defined by {@link #getRole()}
*/
<T, U> void setValue(T element, U value);

// introspection methods
/**
* @return the role handled by this handler
*/
CtRole getRole();

/**
* @return the type of the class, which this handler can be applied to (eg CtMethod)
*/
Class<?> getTargetType();

/**
* @return the type of returned value defined by {@link #getRole()}
*/
Class<?> getValueClass();

/**
* @return the container kind, to know whether an element, a list, a map, etc is returned.
*/
ContainerKind getContainerKind();

// utility methods
/**
* @return a value for this role adapted as a modifiable Collection
*/
<T, U> Collection<U> asCollection(T element);

/**
* @return a value for this role adapted as a modifiable Set
*/
<T, U> Set<U> asSet(T element);

/**
* @return a value for this role adapted as a modifiable List
*/
<T, U> List<U> asList(T element);

/**
* @return a value for this role adapted as a modifiable Map
*/
<T, U> Map<String, U> asMap(T element);
}
Loading