2017-09-18 3 views
0

J'essaie de mettre en œuvre un simple subtyping check pour le checker-framework.
Cela fonctionne essentiellement, mais j'ai une erreur liée à l'utilisation de lambda que je ne comprends pas.Erreur de vérification de sous-type pour lambda

J'ai créé un simple test-projet sur github: checkerfw-test afin que tout le monde puisse facilement reproduire le problème.

Le système de types que j'utilise ressemble beaucoup à l'exemple RegEx dans le docs/src.
est ici un lien vers my types:

  • IdDomainObject est le type haut
  • IdUser, IdCustomer sont les types personnalisés qui ne doivent pas être cessible à l'autre
  • IdBottom est le type de fond

La compilation de mon testFromCallable2() Fonction:

static class GenericHolder<T> { 
    public T field; 
} 

public static <T> GenericHolder<T> fromCallable(final Callable<? extends T> callable) { 
    GenericHolder<T> result = new GenericHolder<T>(); 
    try { 
     result.field = callable.call(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return result; 
} 

public void testFromCallable2() { 
    GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> { 
       final @IdCustomer Long customerId = toCustomerId(1); 
       return customerId; 
      } 
    ); 
} 

échoue avec ce message d'erreur:

 GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> { 

    required: @IdDomainObject GenericHolder<@IdCustomer Long> 

Je ne pense pas que cela devrait échouer, parce que le lambda retourne exactement le type spécifié.

La source de test contient également une fonction testFromCallable1, qui fait la même chose, juste sans lambda et ce code fonctionne:

public void testFromCallable1() { 
    GenericHolder<@IdCustomer Long> tmp = fromCallable(new Callable<@IdCustomer Long>() { 
     @Override 
     public @IdCustomer Long call() throws Exception { 
      final @IdCustomer Long customerId = toCustomerId(1); 
      return customerId; 
     } 
    }); 
} 

Qu'est-ce que je manque?

Note:
Je commence juste à utiliser le vérificateur de sous-type, donc je pense que je n'ai pas encore compris tous les documents sur le sous-typage: par ex. peut-être que je viens de définir quelques mauvaises valeurs pour certaines des annotations sur mon type-définitions (par exemple @ImplicitFor, @DefaultFor, ...)

J'utilise la version checker-cadre 2.2.0

Répondre

1

Le cadre Checker ne encore implémenter pleinement l'inférence de type Java 8. Voir Issue #979. Vous pouvez contourner cette limitation en spécifiant explicitement l'argument de type à fromCallable.

GenericHolder<@IdCustomer Long> tmp2 = this.<@IdCustomer Long>fromCallable(() -> { 
      final @IdCustomer Long customerId = toCustomerId(1); 
      return customerId; 
     } 
); 

testFromCallable1 ne délivre pas l'erreur car il n'utilise pas l'inférence de type Java 8.