Skip to content
This repository has been archived by the owner on Apr 19, 2022. It is now read-only.

Niveau 2 #5

Open
10 tasks
lesaint opened this issue Feb 12, 2015 · 7 comments
Open
10 tasks

Niveau 2 #5

lesaint opened this issue Feb 12, 2015 · 7 comments
Assignees

Comments

@lesaint
Copy link
Collaborator

lesaint commented Feb 12, 2015

talk

Avec un AP, on peut étendre le compilateur => faire de la validation

  • présentation de l'API Writer
  • comment utiliser Processor#getSupportedAnnotationTypes()
  • présentation de javax.lang.model.element.* et javax.lang.model.type.*
    • qu'est-ce qu'un Element ? qu'est-ce qu'un type ?
  • utilisation des visiteurs pour connaître les types réels
  • les exos de validation sont l'occasion d'utiliser compile-testing => le présenter rapidement

exercices

  • exo 1 : validation d'annotations, erreur de compilation déplacé du niveau 3
    • sujet : empêcher @Inject sur les propriétés
    • apprendre en récupérer les annotations "surveillées"
    • 1er contact avec l'API Element/Type + utilisation de Messager
  • exo 2 : et si vous affichiez la ligne à laquelle se trouve l'erreur ? déplacé au niveau 3
    • les paramètres des méthodes de Messager plus en détail
  • exo 3 : et si vous n'affichiez qu'un warning ? déplacé du niveau 3
    • que se passe-t-il ? (rien sous Maven -- je crois)
  • exo 4 : valider qu'une valeur d'un paramètre d'une annotation est unique par package
    • mise en avant de l'aspect statefull de l'AP et de son cycle de vie déjà couvert par la solution bourrin pour traiter le bégaiement du processor au niveau 1
  • exo 5 à Z : connaître l'API javax.lang.model
    • série de tests unitaires dont le code d'exploration de l'API est à écrire
    • sujets multiples, mais il s'agit de découvrir les visiteurs, les classes Elements, Types, ElementFilters, les visiteurs et comment les utiliser
    • le sujet étant vaste, certains exercices pourront être relégué au dernier niveau, pour les plus rapides et pour éviter que ce niveau ne dure trop longtemps
@lesaint
Copy link
Collaborator Author

lesaint commented Feb 12, 2015

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]).

@lesaint
Copy link
Collaborator Author

lesaint commented Feb 12, 2015

Idée pour exo 5 à Z :

extraire toutes les méthodes et constructeurs d'une classe (héritée ou non)

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);

@lesaint
Copy link
Collaborator Author

lesaint commented Feb 12, 2015

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.

lesaint added a commit that referenced this issue Mar 5, 2015
methods in source has not yet been emptied of their implementation
methods have javadoc
README for exo1 is done
lesaint added a commit that referenced this issue Mar 6, 2015
methods in source has not yet been emptied of their implementation
methods have javadoc
README for exo1 is done
lesaint added a commit that referenced this issue Mar 11, 2015
add to use another way of writing unit test again the element and type package because when used outside the annotation processing that created it, the Element returned by the Elements class are not equal to the one that existed during the annotation processing run (cf. http://stackoverflow.com/a/18620582)
lesaint added a commit that referenced this issue Mar 11, 2015
add to use another way of writing unit test again the element and type package because when used outside the annotation processing that created it, the Element returned by the Elements class are not equal to the one that existed during the annotation processing run (cf. http://stackoverflow.com/a/18620582)
@lesaint
Copy link
Collaborator Author

lesaint commented Mar 12, 2015

Je viens de modifier la description de cette issue:

  1. l'exo 4 n'a plus de raison d'être, l'aspect statefull du Processor
    • a déjà été mis en avantau niveau 1 (exo2 étape2, suppression à la bourrin du bégaiement)
    • sera utilisé dans les exercices du niveau3 (génération du fichier des morts de Game Of Thrones par ex.)
  2. comme ce niveau comporte déjà deux exercices assez long qui se concentrent sur l'API, je pense que les autres peuvent être déplacé au niveau 3

@fbiville WDYT ?

lesaint added a commit that referenced this issue Mar 15, 2015
methods in source has not yet been emptied of their implementation
methods have javadoc
README for exo1 is done
lesaint added a commit that referenced this issue Mar 15, 2015
add to use another way of writing unit test again the element and type package because when used outside the annotation processing that created it, the Element returned by the Elements class are not equal to the one that existed during the annotation processing run (cf. http://stackoverflow.com/a/18620582)
fbiville added a commit that referenced this issue Mar 15, 2015
Add some minor README fixes
@fbiville fbiville reopened this Mar 15, 2015
fbiville added a commit that referenced this issue Mar 17, 2015
lesaint added a commit that referenced this issue Mar 17, 2015
unit test tested exactly the opposite of the expected result
lesaint added a commit that referenced this issue Mar 18, 2015
methods in source has not yet been emptied of their implementation
methods have javadoc
README for exo1 is done
lesaint added a commit that referenced this issue Mar 18, 2015
add to use another way of writing unit test again the element and type package because when used outside the annotation processing that created it, the Element returned by the Elements class are not equal to the one that existed during the annotation processing run (cf. http://stackoverflow.com/a/18620582)
fbiville added a commit that referenced this issue Mar 18, 2015
Add some minor README fixes
fbiville added a commit that referenced this issue Mar 18, 2015
lesaint added a commit that referenced this issue Mar 18, 2015
unit test tested exactly the opposite of the expected result
lesaint added a commit that referenced this issue Mar 18, 2015
had to modify unit test to use same DontLookAtThisClass implementation as exo2 which actually supports Element#equals
lesaint added a commit that referenced this issue Mar 18, 2015
in method extractAnnotations, one could use Elements#getAllAnnotationMirrors instead of Elements#getAnnotationMirrors, which is a wrong answer but was not visible with the provided sample Class
@lesaint
Copy link
Collaborator Author

lesaint commented Mar 28, 2015

reste à faire :

  • mettre une présentation de l'API dans le README avant la présentation des exercices
  • nettoyer l'historique de master et supprimer le merge

@fbiville
Copy link
Owner

fbiville commented Apr 7, 2015

Y'a encore des choses à faire ici ?
Ton dernier commentaire est toujours d'actualité ?

@sns-seb
Copy link

sns-seb commented Apr 7, 2015

dernier commentaire toujours d'actualité pour le nettoyage de l'historique, descopable pour ce qui est du README (sera couvert à l'oral)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants