Open lesaint opened 9 years ago
Pour les exos 5 à Z, l'idée est un genre de parcours dirigé des outils dispo et des bonnes pratiques.
Je me dis que pour découvrir l'API javax.lang.model
l'idéal est de résoudre quelques problèmes plus petits (genre : récupérez tous les constructeurs de classe A puis class B -- qui sousclasse A, ...) et de s'absoudre de la problématique AP. On donnerai les liens vers les classes ou méthodes à utiliser et les participants n'auraient qu'à compléter une méthode.
Seulement, je ne vois pas trop comment l'écrire en test U. Ces codes ne peuvent être exécutés que dans le contexte d'un AP. L'alternative étant de mocker l'API javax.lang.model
, je n'y crois pas.
La seule solution que je vois, c'est d'utiliser un AP dont le rôle est de cracher des messages de compilation produits à partir du résultat du code à écrire. Le test U consisterait alors à vérifier avec compile-testing ce qui est affiché. Encore faut-il que compile-testing le permette.
Pour passer d'un test à un autre, je pense soit à avoir plusieurs AP, soit à utiliser les paramètres de l'AP (là aussi, faut vérifier que c'est faisable) pour indiquer quel test exécuter, soit, plus bourrin mais simple, un seul AP exécute toujours tous les tests mais chaque test U ne vérifie qu'un sous ensemble des lignes produits (par exemple, chaque test produit des lignes qui commence par [TEST XX]
).
Idée pour exo 5 à Z :
code de DAMapping
, il faut ignorer la conversion en DAMethod
.
Contient des sous exercices (liste des classes de la hiérarchie, convertir en TypeElement, ...).
@Nonnull
private List<JavaxDAMethod> retrieveMethods(final TypeElement classElement, final JavaxExtractor javaxExtractor) {
List<TypeElement> classHierarchy = extractClassHierarchyAsList(classElement);
List<JavaxDAMethod> res = Lists.of();
for (TypeElement clazz : classHierarchy) {
if (clazz.getEnclosedElements() == null) {
continue;
}
for (JavaxDAMethod javaxDAMethod : from(clazz.getEnclosedElements())
// methods are ExecutableElement
.filter(ExecutableElement.class)
// filter out super class constructors
.filter(
clazz.equals(classElement) ? Predicates.<ExecutableElement>alwaysTrue() : FilterOutConstructor.INSTANCE
)
// transform into object of the DAModel
.transform(new ExecutableElementToJavaxDAMethod(javaxExtractor, classElement))
.filter(notNull())) {
res.add(javaxDAMethod);
}
}
return res;
}
private static enum FilterOutConstructor implements Predicate<ExecutableElement> {
INSTANCE;
@Override
public boolean apply(@Nullable ExecutableElement executableElement) {
return executableElement != null && executableElement.getKind() != ElementKind.CONSTRUCTOR;
}
}
private List<TypeElement> extractClassHierarchyAsList(TypeElement classElement) {
return classElement.accept(new SuperTypeElementsVisitor(), new ArrayList<TypeElement>());
}
@Nullable
private static TypeElement asTypeElement(TypeMirror t) {
DeclaredType declaredType = asDeclaredType(t);
if (declaredType == null) {
return null;
}
return declaredType.asElement().accept(AsTypeElementVisitor.INSTANCE, null);
}
private static class AsTypeElementVisitor extends SimpleElementVisitor6<TypeElement, Void> {
public static final AsTypeElementVisitor INSTANCE = new AsTypeElementVisitor();
private AsTypeElementVisitor() {
// prevents instantiation
}
@Override
public TypeElement visitType(TypeElement e, Void o) {
return e;
}
}
@Nullable
private static DeclaredType asDeclaredType(TypeMirror t) {
return t.accept(AsDeclaredTypeTypeVisitor.INSTANCE, null);
}
private static class AsDeclaredTypeTypeVisitor extends SimpleTypeVisitor6<DeclaredType, Object> {
public static final AsDeclaredTypeTypeVisitor INSTANCE = new AsDeclaredTypeTypeVisitor();
private AsDeclaredTypeTypeVisitor() {
// prevents instantiation
}
@Override
public DeclaredType visitDeclared(DeclaredType t, Object o) {
return t;
}
}
A noter qu'il semble que l'extraction des méthodes aurait pu être codée en exploitant Elements
et ElementFilter
mais on récupère aussi les méthodes de java.lang.Object
(getClass()
, equals()
, ...). Cependant, on a pas le problème de récupérer le constructeur des super class comme dans le code extrait de DAMapping.
List<? extends Element> allMembers = elementUtils.getAllMembers(classElement);
List<ExecutableElement> executableElements = ElementFilter.methodsIn(allMembers);
sur la compréhension de Element
et Type
, extrait de http://docs.oracle.com/javase/7/docs/api/index.html?javax/lang/model/package-summary.html:
In particular, the model makes a distinction between static language constructs, like the element representing java.util.Set, and the family of types that may be associated with an element, like the raw type java.util.Set, java.util.Set
, and java.util.Set .
Je viens de modifier la description de cette issue:
@fbiville WDYT ?
reste à faire :
Y'a encore des choses à faire ici ? Ton dernier commentaire est toujours d'actualité ?
dernier commentaire toujours d'actualité pour le nettoyage de l'historique, descopable pour ce qui est du README (sera couvert à l'oral)
talk
Avec un AP, on peut étendre le compilateur => faire de la validation
exercices
exo 1 : validation d'annotations, erreur de compilationdéplacé du niveau 3exo 2 : et si vous affichiez la ligne à laquelle se trouve l'erreur ?déplacé au niveau 3exo 3 : et si vous n'affichiez qu'un warning ?déplacé du niveau 3exo 4 : valider qu'une valeur d'un paramètre d'une annotation est unique par packagemise en avant de l'aspect statefull de l'AP et de son cycle de viedéjà couvert par la solution bourrin pour traiter le bégaiement du processor au niveau 1javax.lang.model
Elements
,Types
,ElementFilters
, les visiteurs et comment les utiliser