xvik / generics-resolver

Java generics runtime resolver
https://xvik.github.io/generics-resolver
MIT License
45 stars 9 forks source link

Missing a common interface between MethodGenericsContext and ConstructorGenericsContext #6

Open UnasZole opened 4 years ago

UnasZole commented 4 years ago

java.lang.reflect.Constructor and java.lang.reflect.Method all inherit from java.lang.reflect.Executable, which defines all methods related to inspection of the arguments. This allows to make some common code for inspecting the parameters of either a constructor or a method.

Generics-Resolver does not currently expose any such common parent between ConstructorGenericsContext and MethodGenericsContext, so it becomes difficult to share this kind of code when working with generics. (I am currently using a wrapper class around both objects, but this is not very nice)

A quick suggestion is to create an ExecutableGenericsContext interface defining the resolveParametersTypes() and parameterType(final int pos) methods, and a few others. You could probably refactor the lib code a bit to make this a common parent class instead and avoid code duplication, but that's up to you - for the end user, the result will be the same :-)

xvik commented 4 years ago

Good point, this indeed could be unified. Thank you! But, I can't promise to do this soon. I think this will be released with 3.1 when it will be finished.

UnasZole commented 4 years ago

Great, thanks !

In the meantime, if it can help some people, what I'm currently using is a "quick and dirty" wrapper class :

  private static class ExecutableGenericsContext {
    private ConstructorGenericsContext constructorContext;
    private MethodGenericsContext methodContext;

    public ExecutableGenericsContext(ConstructorGenericsContext constructorContext) {
      this.constructorContext = constructorContext;
      this.methodContext = null;
    }

    public ExecutableGenericsContext(MethodGenericsContext methodContext) {
      this.methodContext = methodContext;
      this.constructorContext = null;
    }

    public List<Type> resolveParametersTypes() {
      return constructorContext != null ?
          constructorContext.resolveParametersTypes() :
            methodContext.resolveParametersTypes();
    }

    public GenericsContext parameterType(final int pos) {
      return constructorContext != null ?
          constructorContext.parameterType(pos) :
            methodContext.parameterType(pos);
    } 
  }

That way, when you will add such a common interface, I'll just have to replace references to this class by references to the new interface and it should all be transparent :-)